【问题标题】:Can async/await still deadlock if ConfigureAwait(false) is used?如果使用 ConfigureAwait(false),异步/等待仍然会死锁吗?
【发布时间】:2019-03-06 08:18:07
【问题描述】:

根据this link 的说法,在特定情况下,async/await 可能会发生死锁。

但是,如果我总是使用ConfigureAwait(false),还会出现死锁吗?

例如:task.ConfigureAwait(false).GetAwaiter().GetResult()

代替:task.GetAwaiter().GetResult()

【问题讨论】:

  • 旁注:这是“配置等待”,而不是“配置任务”。 task.ConfigureAwait(false).GetAwaiter().GetResult() 中的 ConfigureAwait(false) 没有任何影响,因为没有要配置的 await

标签: c# async-await deadlock


【解决方案1】:

如果将要完成的任何内容 task 或任何进一步的嵌套操作已捕获您当前的上下文,如果该上下文绑定到特定线程,它仍然可能死锁 - 因为您正在调用 GetResult 使用该线程并阻塞,使其无法供其他人使用。

只需使用awaitawait 可以释放你当前的上下文。

【讨论】:

    【解决方案2】:

    是的,它仍然会死锁,ConfigureAwait(false) 必须在所有嵌套等待中实现,其中一些你可能无法控制。

    最好的办法是不要依赖它,只是不要混合同步和async调用,让Async/Await传播。

    确保它不会死锁(没有await)的唯一可靠方法(并且有争议)是将其卸载 / 包装到另一个任务并@ 987654324@那个,或者在一个没有SynchronizationContext的框架中

    【讨论】:

      【解决方案3】:

      顾名思义,ConfigureAwait() 只影响异步的await。它对Task.Wait()Task.ResultTask.GetAwaiter().GetResult() 等同步等待没有影响。

      ConfigureAwait(false) 大致意思是“我不在乎这个异步等待之后的代码将在哪个线程上恢复”,所以如果原始线程(更准确地说是SynchronizationContext)被某些东西阻塞,它仍然会继续不同的线程。但是像GetAwaiter().GetResult() 这样的同步等待永远不会切换线程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-21
        • 2016-03-24
        • 1970-01-01
        相关资源
        最近更新 更多