await vs Task.Wait - 死锁? [英] await vs Task.Wait - Deadlock?

查看:29
本文介绍了await vs Task.Wait - 死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不太明白 Task.Waitawait 之间的区别.

I don't quite understand the difference between Task.Wait and 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
    }
}

Get 会死锁的地方.

这是什么原因造成的?当我使用阻塞等待而不是 await Task.Delay 时,为什么这不会导致问题?

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

推荐答案

Waitawait - 虽然概念上相似 - 但实际上完全不同.

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

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

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 将异步等待直到任务完成.这意味着当前的方法被暂停"(它的状态被捕获)并且该方法向其调用者返回一个未完成的任务.稍后,当 await 表达式完成时,该方法的其余部分被安排为延续.

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.

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

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).

您可能会找到我的 async/<代码>等待介绍很有帮助.

You may find my async / await intro helpful.

这篇关于await vs Task.Wait - 死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆