Coder Perfect

When should you use Task.Delay and when should you use Thread.Sleep?

Problem

Is there a suitable rule to follow when deciding whether to utilize Task.Delay or Thread.Sleep?

Asked by Tom K.

Solution #1

Make use of thread. When you wish to block the current thread, go to sleep.

When you need a logical delay without halting the current thread, use Task.Delay.

With these strategies, efficiency should not be a top priority. Their principal application in the actual world is as retry timers for I/O operations that take seconds rather than milliseconds.

Answered by Stephen Cleary

Solution #2

The most significant distinction between Task.Delay and Thread. That task is to sleep. Delay is designed to work in an asynchronous manner. Using Task is not a good idea. In synchronous coding, there is a delay. Using Thread is a terrible idea. In asynchronous code, you can sleep.

Task.Delay() is normally called using the await keyword:

await Task.Delay(5000);

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

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

What do you think this will print? 0.0070048 seconds have passed. If we move the await delay above the Console, we’ll have a better result. Instead, it will print Running for 5.0020168 seconds if you use WriteLine.

Let’s have a look at how Thread differs. 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");
    }
}

Make an educated guess as to what this will print…

It’s also worth noting that Thread.Sleep is significantly more exact, with ms accuracy not being an issue, whereas Task.Sleep is not. Delay might be as little as 15-30 milliseconds. When compared to the ms accuracy of both functions, the overhead is negligible (use Stopwatch Class if you need something more accurate). Task, Thread.Sleep still binds your Thread. Delay releasing it so you can get some other stuff done while you wait.

Answered by Dorus

Solution #3

I’d like to make a suggestion. Task, to be precise. Delay is a wait mechanism that uses a timer. A reference to a Timer class, which is responsible for the delay, can be found in the source. Thread, on the other hand. Sleep actually sleeps the current thread, thus you’re only blocking and wasting one thread. Always use Task in an async programming architecture. If you want something (continuation) to happen after a wait, use Delay().

Answered by crypted

Solution #4

If you use Thread.Sleep while the current thread is still running, you can obtain a ThreadAbortException. You may always give a cancellation token and gracefully kill it with Task.Delay. That’s one of the reasons I’d go with Task.Delay. http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx for more information.

I agree that efficiency isn’t the most important factor in this circumstance.

Answered by Mr Balanikas

Solution #5

Task’s name should be changed to Delayed. Delay – because it does not delay an existing task but instead produces a new ‘delayed’ one that can be awaited and can cause the current task’s body to be suspended. It’s similar to a Timer, but without the callback or body.

Awaiting a delayed job adds a new item to the async message queue without blocking other threads. If there are any other tasks, the thread where await is called will continue working on them before returning to the await point after the timeout (or when the preceding items in queue are complete). Threads are used by Tasks beneath the hood, and a single thread can have multiple Tasks scheduled and executed. If you call Thread.Sleep(), on the other hand, the thread will block, meaning it will be out of action for the amount of time specified and will not process any async messages from the queue.

There are two major ways to parallelism in.NET. The one having Threads, ThreadPools, and so on. And then there’s the new one, which is based on Tasks, async/await, and TPL. As a general rule, APIs from these two universes should not be mixed.

Answered by telepuz

Post is based on https://stackoverflow.com/questions/20082221/when-to-use-task-delay-when-to-use-thread-sleep