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?
Waitandawait– while similar conceptually – are actually completely different.Waitwill 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 “asyncall the way down”; that is, don’t block onasynccode. On my blog, I go into the details of how blocking in asynchronous code causes deadlock.awaitwill 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 theawaitexpression 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:Waitcannot execute theDelaytask inline because there’s no code for it).You may find my
async/awaitintro helpful.