ConfigureAwait(false) 维护线程身份验证,但默认情况下不
Posted
技术标签:
【中文标题】ConfigureAwait(false) 维护线程身份验证,但默认情况下不【英文标题】:ConfigureAwait(false) maintains thread authentication but by default it doesn't 【发布时间】:2019-04-27 04:14:48 【问题描述】:我有一个简单的 Web API 操作方法,其中包含以下代码 sn-p
Debug.WriteLine("Before async method call id: " + Thread.CurrentThread.ManagedThreadId);
Debug.WriteLine("Before async method call auth: " + Thread.CurrentPrincipal.Identity.IsAuthenticated);
var result = await SomeAsyncMethod();
Debug.WriteLine("After async method call id: " + Thread.CurrentThread.ManagedThreadId);
Debug.WriteLine("After async method call auth: " + Thread.CurrentPrincipal.Identity.IsAuthenticated);
此代码打印出以下内容:
Before async method call id: 257
Before async method call auth: True
After async method call id: 268
After async method call auth: False
请注意,在 await 调用之后,主线程现在是未经身份验证的。但是,如果我像下面这样使用 ConfigureAwait(false):
Debug.WriteLine("Before async method call id: " + Thread.CurrentThread.ManagedThreadId);
Debug.WriteLine("Before async method call auth: " + Thread.CurrentPrincipal.Identity.IsAuthenticated);
var result = await SomeAsyncMethod().ConfigureAwait(false);
Debug.WriteLine("After async method call id: " + Thread.CurrentThread.ManagedThreadId);
Debug.WriteLine("After async method call auth: " + Thread.CurrentPrincipal.Identity.IsAuthenticated);
我看到下面的输出:
Before async method call id: 268
Before async method call auth: True
After async method call id: 242
After async method call auth: True
我对 ConfigureAwait(false) 的理解是代码在不同的线程中运行 不知道原始线程的上下文(身份验证等)。因此,它最适合第三方库。
根据以上观察,我有以下问题-
-
异步调用前后线程 ID 的变化。不应该在调用异步方法的主线程上恢复吗?
即使调用在不同的线程上恢复(如示例中所示),它是否应该在主线程的相同上下文中恢复(即 IsAuthenticated 必须为真)?为什么使用 ConfigureAwait(false) 验证保持 true 而不是其他情况?
谢谢!
【问题讨论】:
***.com/questions/21390186/… 可能重复。 【参考方案1】:特定线程在 ASP.NET 中并不重要。请求由线程池中的任何可用线程提供服务。
重要的是同步上下文。
ConfigureAwait(false)
指示编译器生成的状态机将延续调度到线程池,而不是将它们发布到捕获的同步上下文(如果已捕获)。
同步上下文使用正确的线程数据和线程静态设置调度线程池线程。
您不应在操作方法上调用 ConfigureAwait(false)
,因为您无法保证线程数据是您所期望的。
不管是否有同步上下文,异步代码都会在线程间流动逻辑调用上下文。并且,随之而来的是当前的本金。
【讨论】:
谢谢保罗。我明白这一点;但是,我正在寻找有关上述特定场景/用例的更多解释。您的答案更多是在概念层面上。以上是关于ConfigureAwait(false) 维护线程身份验证,但默认情况下不的主要内容,如果未能解决你的问题,请参考以下文章
为整个项目/dll 设置 ConfigureAwait(false)
ConfigureAwait(false) 与将同步上下文设置为 null
您可以在没有线程安全的情况下使用 ConfigureAwait(false) 吗?