Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Task.Delay, when to use Thread.Sleep?

Are there good rule(s) for when to use Task.Delay versus Thread.Sleep?

  • Specifically, is there a minimum value to provide for one to be effective/efficient over the other?
  • Lastly, since Task.Delay causes context-switching on a async/await state machine, is there an overhead of using it?
like image 833
Tom K. Avatar asked Nov 19 '13 21:11

Tom K.


People also ask

Should I use Task delay or thread sleep?

Use Thread. Sleep when you want to block the current thread. Use Task. Delay when you want a logical delay without blocking the current thread.

Should I use Task or thread?

It is always advised to use tasks instead of thread as it is created on the thread pool which has already system created threads to improve the performance. The task can return a result. There is no direct mechanism to return the result from a thread.

Does Task delay block thread?

Delay(1000) doesn't block the thread, unlike Task. Delay(1000).

Does Task delay create a new thread?

Task. Delay does not create new Thread, but still may be heavy, and no guaranties on order of execution or being precise about deadlines.


2 Answers

Use Thread.Sleep when you want to block the current thread.

Use Task.Delay when you want a logical delay without blocking the current thread.

Efficiency should not be a paramount concern with these methods. Their primary real-world use is as retry timers for I/O operations, which are on the order of seconds rather than milliseconds.

like image 136
Stephen Cleary Avatar answered Sep 28 '22 06:09

Stephen Cleary


The biggest difference between Task.Delay and Thread.Sleep is that Task.Delay is intended to run asynchronously. It does not make sense to use Task.Delay in synchronous code. It is a VERY bad idea to use Thread.Sleep in asynchronous code.

Normally you will call Task.Delay() with the await keyword:

await Task.Delay(5000); 

or, if you want to run some code before the delay:

var sw = new Stopwatch(); sw.Start(); Task delay = Task.Delay(5000); Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds); await delay; 

Guess what this will print? Running for 0.0070048 seconds. If we move the await delay above the Console.WriteLine instead, it will print Running for 5.0020168 seconds.

Let's look at the difference with 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");     } } 

Try to predict what this will print...

async: Starting
async: Running for 0.0070048 seconds
sync: Starting
async: Running for 5.0119008 seconds
async: Done
sync: Running for 5.0020168 seconds
sync: Done

Also, it is interesting to notice that Thread.Sleep is far more accurate, ms accuracy is not really a problem, while Task.Delay can take 15-30ms minimal. The overhead on both functions is minimal compared to the ms accuracy they have (use Stopwatch Class if you need something more accurate). Thread.Sleep still ties up your Thread, Task.Delay release it to do other work while you wait.

like image 39
Dorus Avatar answered Sep 28 '22 06:09

Dorus