Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await vs Task.Wait - Deadlock?

I don't quite understand the difference between Task.Wait and await.

I have something similar to the following functions in a ASP.NET WebAPI service:

public class TestController : ApiController
{
    public static async Task<string> Foo()
    {
        await Task.Delay(1).ConfigureAwait(false);
        return "";
    }

    public async static Task<string> Bar()
    {
        return await Foo();
    }

    public async static Task<string> Ros()
    {
        return await Bar();
    }

    // GET api/test
    public IEnumerable<string> Get()
    {
        Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());

        return new string[] { "value1", "value2" }; // This will never execute
    }
}

Where Get will deadlock.

What could cause this? Why doesn't this cause a problem when I use a blocking wait rather than await Task.Delay?

like image 414
ronag Avatar asked Oct 21 '22 22:10

ronag


People also ask

Does await block the current thread?

The await operator doesn't block the thread that evaluates the async method. When the await operator suspends the enclosing async method, the control returns to the caller of the method.

What is task deadlock?

If you block the UI thread there is nothing left to execute tasks and you have a deadlock. If you're writing a dotnet core web application, you're basically running everything on the thread pool. Any blocking code will block the thread pool and any . Result will lead to a deadlock.

What is task wait?

Wait is a synchronization method that causes the calling thread to wait until the current task has completed. If the current task has not started execution, the Wait method attempts to remove the task from the scheduler and execute it inline on the current thread.

What is the difference between wait and await C#?

'Wait' means to pass the time until an anticipated event occurs, whereas 'await' means to wait for something with a hope.


2 Answers

Wait and await - while similar conceptually - are actually completely different.

Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use "async all the way down"; that is, don't block on async code. On my blog, I go into the details of how blocking in asynchronous code causes deadlock.

await will asynchronously wait until the task completes. This means the current method is "paused" (its state is captured) and the method returns an incomplete task to its caller. Later, when the await expression completes, the remainder of the method is scheduled as a continuation.

You also mentioned a "cooperative block", by which I assume you mean a task that you're Waiting on may execute on the waiting thread. There are situations where this can happen, but it's an optimization. There are many situations where it can't happen, like if the task is for another scheduler, or if it's already started or if it's a non-code task (such as in your code example: Wait cannot execute the Delay task inline because there's no code for it).

You may find my async / await intro helpful.

like image 357
Stephen Cleary Avatar answered Oct 23 '22 10:10

Stephen Cleary


Based on what I read from different sources:

An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

To wait for a single task to complete, you can call its Task.Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The parameterless Wait() method is used to wait unconditionally until a task completes. The task simulates work by calling the Thread.Sleep method to sleep for two seconds.

This article is also a good read.

like image 23
Ayushmati Avatar answered Oct 23 '22 10:10

Ayushmati