joedotnot
joedotnot

Reputation: 5133

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!

Upvotes: 2

Views: 1224

Answers (4)

Christophe
Christophe

Reputation: 699

Use

Task.Delay(5000).Wait();

This is because you need to wait for the task to complete before continuing.

Upvotes: 0

Udontknow
Udontknow

Reputation: 1578

Task.Delay() creates a task that completes after the given time. You just created a task, and that completes very fast.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499810

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.

Upvotes: 8

Philip Stuyck
Philip Stuyck

Reputation: 7447

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.

Upvotes: 1

Related Questions