- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
当编译器遇到 await
时,它会将 async
方法转换为状态机,并通过
AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted
概述 here或 AsyncTaskMethodBuilder.AwaitOnCompleted
概述 here .
查看 .NET 源代码 here ,AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted
调用 Awaiter.UnSafeOnCompleted
Awaiter.UnSafeOnCompleted
似乎没有流向 ExecutionContext(代码 here)。
注意它将 false
传递给 flowExecutionContext
。这意味着如果我使用 LogicalCallContext
(ExecutionContext
的一部分)来存储任何数据(例如 activityId),那么它不会在继续路径中流动,这意味着我无法访问它。
那么,我的问题是是什么导致编译器选择不安全完成?
Stephen Toub 也提到了同样的事情here但没有给出任何细节。“.NET Framework 中的所有派生异步工作的方法都以这样的方式捕获和恢复 ExecutionContext(也就是说,除了那些以单词“不安全”为前缀的方法之外,它们是不安全的,因为它们明确地不流执行上下文”
最佳答案
This means if I am using
LogicalCallContext
[...] to store any data [...] then it wont be flowed in continuation path
不完全是。 OnCompleted
只是执行上下文流动的可能方式之一。您需要排除它可能流动的其他方式。
So, my question is what causes the compiler to choose Unsafe Completion ?
编译器将尽可能使用它(即每当 ICriticalNotifyCompletion
被实现时)。
但是,编译器也间接依赖于 AsyncMethodBuilderCore
,这确实会导致执行上下文流动,通过其 MoveNextRunner
辅助类。在这种情况下,它设法通过仅存储对执行上下文的单个引用而不是每个延续的一个引用来更有效地做到这一点。
除非您特意阻止执行上下文流动,否则您无需担心。
关于c# - AsyncTaskMethodBuilder AwaitUnsafeOnCompleted 与等待时的 AwaitOnCompleted,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45872860/
当编译器遇到 await 时,它会将 async 方法转换为状态机,并通过 安排继续 AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted 概述 here或 As
我是一名优秀的程序员,十分优秀!