ConfigureAwait(false)保持线程身份验证,但默认情况下不会

时间:2018-11-25 07:28:32

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

我有一个简单的Web API操作方法,其中包含以下代码段

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

请注意,等待调用后,主线程现在未经过身份验证。但是,如果使用如下所示的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必须为true)吗?为什么身份验证通过ConfigureAwait(false)保持为true,否则为非?

谢谢!

1 个答案:

答案 0 :(得分:0)

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

重要的是同步上下文。

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

是同步上下文,它使用适当的线程数据和线程静态变量来设置计划线程池线程。

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

尽管具有同步上下文,但异步代码使逻辑调用上下文跨线程流动。而且,这样,当前主体就可以流动了。