Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task Parallel Library - Task.Delay() usage

I am after some explanation of what's going on.

//VERSION: Async
private async void DoWorkAsync()
{
    Stopwatch stpWatch = new Stopwatch();
    _logger.WriteToLog("Doing some work...etc + ThreadID=" + Thread.CurrentThread.ManagedThreadId);
    stpWatch.Start();

    await Task.Delay(5000);

    stpWatch.Stop();
    _logger.WriteToLog("Work finished on ThreadID=" + Thread.CurrentThread.ManagedThreadId + " ElapsedTime:" + stpWatch.ElapsedMilliseconds);
}

Called as follows:

//loop 10 times
Parallel.For(1, 11, p => DoWorkAsync()); 

So far so good. The tasks do get delayed by approx 5 seconds as expected. (although the Parallel.For loop completes before, as expected).

However if i write the sync version of the above method:

//VERSION: Synchronous
private void DoWork()
{
        Stopwatch stpWatch = new Stopwatch();
        _logger.WriteToLog("Doing some work...etc + ThreadID=" + Thread.CurrentThread.ManagedThreadId);
        stpWatch.Start();

        Task.Delay(5000);

        stpWatch.Stop();
        _logger.WriteToLog("Work finished on ThreadID=" + Thread.CurrentThread.ManagedThreadId + " ElapsedTime:" + stpWatch.ElapsedMilliseconds);
}

i.e. i removed the async/await keywords, and call similarly with

Parallel.For(1, 11, p => DoWork());

, there is no 5 secs delay as before and tasks complete almost immediately (as verified by my log file).

The Task.Delay statement seems to have no effect in the latter case, can i not use it without await keyword?

Hoping some TPL guru is able to explain what's going on please!

like image 256
joedotnot Avatar asked Apr 24 '26 23:04

joedotnot


2 Answers

The Task.Delay statement seems to have no effect in the latter case, can i not use it without await keyword?

Well you can't use it without doing something with the result. Task.Delay just returns a task that will complete later on. That's all it does. It doesn't - in itself - "do" anything to the current thread. Using await then schedules a callback to execute the rest of the async method when that task has completed, and returns control to the caller after scheduling the callback.

If you're looking for the synchronous equivalent of Task.Delay, that's basically Thread.Sleep.

like image 108
Jon Skeet Avatar answered Apr 26 '26 12:04

Jon Skeet


The reason for this is that you don't await the delay anymore, the processing just continues. In fact you don't have a delay anymore that way.

You need to replace the task.delay with a Thread.Sleep.

like image 26
Philip Stuyck Avatar answered Apr 26 '26 12:04

Philip Stuyck



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!