AsyncTaskMethodBuilder AwaitUnsafeOnCompleted 与等待时的 AwaitOnCompleted
AsyncTaskMethodBuilder AwaitUnsafeOnCompleted vs AwaitOnCompleted on await
当编译器遇到 await
时,它会将 async
方法转换为状态机,并通过
安排继续
AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted
概述 here or AsyncTaskMethodBuilder.AwaitOnCompleted
as outlined here。
查看 .NET 源代码here,
AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted
调用 Awaiter.UnSafeOnCompleted
似乎 Awaiter.UnSafeOnCompleted
不流 ExecutionContext(代码 here)。
注意它将 false
传递给 flowExecutionContext
。这意味着如果我使用 LogicalCallContext
(ExecutionContext
的一部分)来存储任何数据(例如 activityId),那么它不会在继续路径中流动,这意味着我无法访问它。
所以,我的问题是是什么导致编译器选择不安全完成?
Stephen Toub 也提到了同样的事情 here 但没有给出任何细节。
"All of the methods in the .NET Framework that fork asynchronous work capture and restore ExecutionContext in a manner like this (that is, all except for those prefixed with the word “Unsafe,” which are unsafe because they explicitly do not flow 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
助手 class 流动。在这种情况下,这设法通过仅存储对执行上下文的单个引用而不是每个延续的一个引用来更有效地做到这一点。
除非您特意阻止执行上下文流动,否则您无需担心。
当编译器遇到 await
时,它会将 async
方法转换为状态机,并通过
AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted
概述 here or AsyncTaskMethodBuilder.AwaitOnCompleted
as outlined here。
查看 .NET 源代码here,
AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted
调用 Awaiter.UnSafeOnCompleted
似乎 Awaiter.UnSafeOnCompleted
不流 ExecutionContext(代码 here)。
注意它将 false
传递给 flowExecutionContext
。这意味着如果我使用 LogicalCallContext
(ExecutionContext
的一部分)来存储任何数据(例如 activityId),那么它不会在继续路径中流动,这意味着我无法访问它。
所以,我的问题是是什么导致编译器选择不安全完成?
Stephen Toub 也提到了同样的事情 here 但没有给出任何细节。 "All of the methods in the .NET Framework that fork asynchronous work capture and restore ExecutionContext in a manner like this (that is, all except for those prefixed with the word “Unsafe,” which are unsafe because they explicitly do not flow 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
助手 class 流动。在这种情况下,这设法通过仅存储对执行上下文的单个引用而不是每个延续的一个引用来更有效地做到这一点。
除非您特意阻止执行上下文流动,否则您无需担心。