ConfigureAwait(false)的正确用法及两种写法的区别是什么?
ConfigureAwait(false)两种写法的对比说明
正确性结论
两种写法均为正确用法,在仅做单次await的场景下,最终运行效果完全一致,都能实现异步等待结束后不捕获还原原始同步上下文的作用。
具体差异
- 存储的变量类型不同
第一种写法:
这里var taskOne = _service.MethodOneAsync(); var taskTwo = _service.MethodTwoAsync(); var responseFromOne = await taskOne.ConfigureAwait(false); var responseFromTwo = await taskTwo.ConfigureAwait(false);taskOne、taskTwo的类型是原生的Task<TResult>,你可以随时对这两个任务对象调用其他Task相关API,比如组合Task.WhenAll(taskOne, taskTwo)、传入其他方法处理、多次await等等。ConfigureAwait(false)仅在await执行前调用,生成对应的可等待结构直接被消费。
第二种写法:
这里var taskOne = _service.MethodOneAsync().ConfigureAwait(false); var taskTwo = _service.MethodTwoAsync().ConfigureAwait(false); var responseFromOne = await taskOne; var responseFromTwo = await taskTwo;taskOne、taskTwo的类型是ConfiguredTaskAwaitable<TResult>,它不是Task的子类,也无法转换回原Task对象,后续如果需要使用Task的相关API(比如任务组合、批量等待、缓存复用等)都无法实现。 - 适用场景不同
如果你的代码只需要对这两个任务各做一次await,不需要其他额外操作,两种写法可以任选,没有性能或者功能上的区别。
如果你需要对任务做除了单次await之外的其他处理,必须选择第一种写法,保留原生Task对象。
常见误区
ConfigureAwait(false)仅控制await之后代码恢复执行时的上下文调度行为,不会对异步方法本身的执行逻辑产生任何影响,也不会改变任务的启动时机:不管你什么时候调用ConfigureAwait,只要执行了_service.MethodOneAsync(),这个异步任务就已经开始运行,和ConfigureAwait的调用时机没有任何关系。
内容的提问来源于stack exchange,提问作者Vinit Divekar
相关产品推荐
相关产品推荐

