【问题标题】:ConfigureAwait(false) maintains thread authentication but by default it doesn'tConfigureAwait(false) 维护线程身份验证,但默认情况下不
【发布时间】: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) 的理解是代码在不同的线程中运行 不知道原始线程的上下文(身份验证等)。因此,它最适合第三方库。

根据以上观察,我有以下问题-

  1. 异步调用前后线程 ID 的变化。不应该在调用异步方法的主线程上恢复吗?
  2. 即使调用在不同的线程上恢复(如示例中所示),它是否应该在主线程的相同上下文中恢复(即 IsAuthenticated 必须为真)?为什么使用 ConfigureAwait(false) 验证保持 true 而不是其他情况?

谢谢!

【问题讨论】:

标签: c# asp.net multithreading asp.net-web-api async-await


【解决方案1】:

特定线程在 ASP.NET 中并不重要。请求由线程池中的任何可用线程提供服务。

重要的是同步上下文。

ConfigureAwait(false) 指示编译器生成的状态机将延续调度到线程池,而不是将它们发布到捕获的同步上下文(如果已捕获)。

同步上下文使用正确的线程数据和线程静态设置调度线程池线程。

您不应在操作方法上调用 ConfigureAwait(false),因为您无法保证线程数据是您所期望的。

不管是否有同步上下文,异步代码都会在线程间流动逻辑调用上下文。并且,随之而来的是当前的本金。

【讨论】:

  • 谢谢保罗。我明白这一点;但是,我正在寻找有关上述特定场景/用例的更多解释。您的答案更多是在概念层面上。
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 2013-01-27
相关资源
最近更新 更多