小编典典

await vs Task.Wait - 死锁?

all

我不太明白 和 之间的Task.Wait区别await

我在 ASP.NET WebAPI 服务中有类似于以下函数的东西:

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
    }
}

哪里Get会死机。

什么可能导致这种情况?当我使用阻塞等待而不是 时,为什么这不会导致问题await Task.Delay


阅读 92

收藏
2022-05-26

共1个答案

小编典典

Waitawait- 虽然在概念上相似 - 实际上是完全不同的。

Wait将同步阻塞,直到任务完成。因此,当前线程实际上被阻塞,等待任务完成。作为一般规则,您应该使用“async一直向下”;也就是说,不要阻塞async代码。在我的博客中,我详细介绍了异步代码中的阻塞如何导致死锁

await将异步等待任务完成。这意味着当前 方法
“暂停”(其状态被捕获)并且该方法向其调用者返回一个不完整的任务。稍后,当await表达式完成时,该方法的其余部分被安排为延续。

您还提到了一个“合作块”,我假设您的意思是您正在Wait处理的任务可能在等待线程上执行。在某些情况下可能会发生这种情况,但这是一种优化。在许多情况下它
不会
发生,例如任务是否用于另一个调度程序,或者它已经启动或者它是非代码任务(例如在您的代码示例中:Wait无法Delay内联执行任务,因为没有代码为了它)。

您可能会发现我的async/await介绍很有帮助。

2022-05-26