问题描述
我不明白 Task.Wait
和的await
。
我有一个ASP.NET的WebAPI服务类似于以下一些功能:
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
}
}
其中,获取
将死锁。
这是什么原因?为什么当我使用屏蔽不会这会带来问题等,而不是等待Task.Delay
?
What could cause this? Why doesn't this cause a problem when I use a blocking wait rather than await Task.Delay
?
推荐答案
等待
和等待
- 而类似概念 - 实际上是完全不同的。
Wait
and await
- while similar conceptually - are actually completely different.
等待
将同步阻塞,直到任务完成。因此,当前线程阻塞字面上等待任务完成。作为一般规则,你应该使用异步
一路下滑;也就是说,不要在阻止异步
code。在我的博客,我进入。
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
将异步等待,直到任务完成。这意味着当前的方法的是暂停(其状态被捕获),并且该方法返回一个不完整的任务,它的调用者。后来,等待
前pression完成时,该方法的其余部分作为计划的延续。
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.
您也提到了合作块,由我假设你的意思,你是等待一个任务
ING上可等待的线程上执行。在有些情况下这可能发生的情况,但它是一个最优化。有很多情况下它的无法的发生,就像如果任务是另一个schedler,或者如果它已经开始,或者如果它是一个非code的任务(如在code例如:等待
,因为没有code它不能执行延迟
任务在线)
You also mentioned a "cooperative block", by which I assume you mean a task that you're Wait
ing 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 schedler, 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.
这篇关于等待VS Task.Wait - 死机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!