[c#] 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?

This question is related to c# multithreading task-parallel-library

The answer is


My opinion,

Task.Delay() is asynchronous. It doesn't block the current thread. You can still do other operations within current thread. It returns a Task return type (Thread.Sleep() doesn't return anything ). You can check if this task is completed(use Task.IsCompleted property) later after another time-consuming process.

Thread.Sleep() doesn't have a return type. It's synchronous. In the thread, you can't really do anything other than waiting for the delay to finish.

As for real-life usage, I have been programming for 15 years. I have never used Thread.Sleep() in production code. I couldn't find any use case for it. Maybe that's because I mostly do web application development.


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.


if the current thread is killed and you use Thread.Sleep and it is executing then you might get a ThreadAbortException. With Task.Delay you can always provide a cancellation token and gracefully kill it. Thats one reason I would choose Task.Delay. see http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx

I also agree efficiency is not paramount in this case.


I want to add something. Actually, Task.Delay is a timer based wait mechanism. If you look at the source you would find a reference to a Timer class which is responsible for the delay. On the other hand Thread.Sleep actually makes current thread to sleep, that way you are just blocking and wasting one thread. In async programming model you should always use Task.Delay() if you want something(continuation) happen after some delay.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to multithreading

How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Waiting until the task finishes What is the difference between Task.Run() and Task.Factory.StartNew() Why is setState in reactjs Async instead of Sync? What exactly is std::atomic? Calling async method on button click WAITING at sun.misc.Unsafe.park(Native Method) How to use background thread in swift? What is the use of static synchronized method in java? Locking pattern for proper use of .NET MemoryCache

Examples related to task-parallel-library

What is the difference between Task.Run() and Task.Factory.StartNew() Task.Run with Parameter(s)? HttpClient - A task was cancelled? Running multiple async tasks and waiting for them all to complete Deserialize JSON to Array or List with HTTPClient .ReadAsAsync using .NET 4.0 Task pattern Calling async method synchronously How can I tell Moq to return a Task? When to use Task.Delay, when to use Thread.Sleep? Awaiting multiple Tasks with different results How to safely call an async method in C# without await