Największa różnica między Task.Delay
i Thread.Sleep
polega na tym, że Task.Delay
ma on działać asynchronicznie. Nie ma sensu używać Task.Delay
w kodzie synchronicznym. Używanie Thread.Sleep
w kodzie asynchronicznym jest BARDZO złym pomysłem .
Zwykle zadzwonisz Task.Delay()
ze await
słowem kluczowym:
await Task.Delay(5000);
lub, jeśli chcesz uruchomić jakiś kod przed opóźnieniem:
var sw = new Stopwatch();
sw.Start();
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;
Zgadnij, co to wydrukuje? Działa przez 0,0070048 sekund. Jeśli zamiast tego przeniesiemy await delay
powyższe Console.WriteLine
, zostanie wydrukowany Uruchomiony przez 5.0020168 sekund.
Spójrzmy na różnicę w Thread.Sleep
:
class Program
{
static void Main(string[] args)
{
Task delay = asyncTask();
syncCode();
delay.Wait();
Console.ReadLine();
}
static async Task asyncTask()
{
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("async: Starting");
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine("async: Done");
}
static void syncCode()
{
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("sync: Starting");
Thread.Sleep(5000);
Console.WriteLine("sync: Running for {0} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine("sync: Done");
}
}
Spróbuj przewidzieć, co to wydrukuje ...
async: Uruchamianie
asynchronizacji: Uruchamianie przez 0,0070048 sekund
Synchronizacja: Uruchamianie
asynchronizacji: Uruchamianie 5,0119008 sekund Asynchronizacja
: Gotowe
Synchronizacja: Uruchamianie 5.0020168 sekund
Synchronizacja: Gotowe
Warto również zauważyć, że Thread.Sleep
jest o wiele dokładniejszy, dokładność ms nie jest tak naprawdę problemem, a Task.Delay
może zająć minimum 15-30 ms. Narzut na obie funkcje jest minimalny w porównaniu z dokładnością ms, jaką mają (użyj Stopwatch
klasy, jeśli potrzebujesz czegoś dokładniejszego). Thread.Sleep
nadal wiąże Wątek, Task.Delay
zwolnij go, aby mógł wykonać inną pracę podczas oczekiwania.