当不涉及真正的I / O调用时,是否需要在异步链的所有级别上使用ConfigureAwait(false)?

时间:2019-07-16 10:03:57

标签: c# azure async-await configureawait

在Azure文档Db客户端SDK之上实现可重用的适配器类型的库。

该库不仅可以在ASP.NET Core Web服务中运行,还可以在命令行应用程序,ASP.NET Web Api等中运行。

在此库中,所有方法都是异步的,它们只是抽象层,使使用Document Db客户端api更加容易。唯一真正的异步调用-I / O请求-实际上是由Document Db SDK中的api在最底层完成的。我上面写的任何代码都只是在内存数据转换,转换中,不涉及实际的I / O调用,但它们也都是异步的,因为最低层的Document Db api是异步的。

我是否仍需要在堆栈中所有高层代码的所有层上使用ConfigureAwait(false),还是足以仅在调用Document Db SDK的我自己代码的最低层上调用ConfigureAwait(False)真正的I / O调用的s方法?

2 个答案:

答案 0 :(得分:2)

property用于防止在初始Foo.bar上执行。如果您正在使用不需要访问UI线程的库(例如WPF或WinForms),则应在所有级别使用ConfigureAwait(false)。否则SynchronizationContext将被恢复。这是一个简单的WinForms应用程序的示例:

ConfigureAwait(false)

输出:

SynchronizationContext

答案 1 :(得分:1)

与在await调用之前的同步代码不同,延续在不同的调用堆栈调用的上下文中执行。特别是,它们被安排为作为单独的委托执行,并且它们之间没有调用堆栈关系。因此,为最后一个延续执行指定ConfigureAwait(false)仅对特定的延续有效,其他延续仍将使用其各自的调度配置执行。也就是说,如果您的目标是确保不通过库中的任何延续来捕获同步上下文(以防止潜在的死锁或任何其他原因),则应配置所有以{{ 1}}。