c# - await vs Task.Wait - 死锁?

标签 c# task-parallel-library deadlock async-await

我不太明白 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 时,为什么这不会导致问题? ?

最佳答案

Waitawait - 虽然概念上相似 - 实际上完全不同。
Wait将同步阻塞,直到任务完成。所以当前线程实际上被阻塞等待任务完成。作为一般规则,您应该使用“async 一直向下”;也就是说,不要阻止 async代码。在我的博客上,我详细介绍了how blocking in asynchronous code causes deadlock .
await将异步等待直到任务完成。这意味着当前方法被“暂停”(它的状态被捕获)并且该方法向其调用者返回一个未完成的任务。后来,当await表达式完成,方法的其余部分被安排为延续。

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

你可能会找到我的 async / await intro有帮助。

关于c# - await vs Task.Wait - 死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67330311/

相关文章:

database - golang 数据库/sql 中的死锁

mysql - 如果不存在则插入行而不会出现死锁

c# - 默认情况下 IServiceProvider 是如何注入(inject)的?

c# - 将二进制 32 位 IEEE-754 浮点转换为 .net 中的 Double

c# - 使用 Parallel.ForEach 对多线程的依赖

c# - 何时锁定 .net 中的线程安全集合? (&什么时候不锁定?)

multithreading - 什么类型的图表最适合可视化线程问题,例如争用?

c# - 墓碑后恢复歌曲播放

c# - 为什么我不能使用 var 声明一个字段

c# - 创建代表一系列连续任务的任务