我已经开始对所有异步sql对象使用ConfigureAwait(false)
。
connection.OpenAsync().ConfigureAwait(false);
cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
但我担心的是,这种方法会有什么影响吗?
由于这将在一个线程池上运行,该线程池是它起源的单独线程,我不确定如果我们不在单个线程上运行它的后果。
我们的应用程序是 wcf 服务,它将并行处理 1000 条记录。
如果有人帮助识别可能是问题的业务场景,那将是有帮助的。
谢谢
作为一般规则,只要异步操作区域是自包含且独立的,就应该可以使用ConfigureAwait(false)
- 事实上,这样做对于减少开销和瓶颈非常重要。库代码通常不需要知道调用上下文。但是,使用代码(如 winforms、MVC 等)通常需要返回到适当的上下文,因此不应使用ConfigureAwait(false)
。例如:
async Task SomeUXCodeAsync() {
var data = await GetSomeDataAsync(); // note no ConfigureAwait(false)
// not shown: use "data"
}
async Task<Foo> GetSomeDataAsync() {
using(var conn = CreateConnection()) {
await conn.OpenAsync().ConfigureAwait(false);
...
int result = await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
...
return ...
}
}
上述场景非常典型和常见,但它比这更复杂 - 例如,注释中的TransactionScope
示例涉及数据相关代码可能需要了解调用上下文的示例。但撇开细微差别不谈:只要消费代码记住不要忽略调用上下文,您通常会回到正确的位置。抱歉,这有点模糊和毛茸茸的,但是:可悲的是,对于调用上下文来说,情况通常是这样。