2
votes

I have a simple Web API action method which has following code snippet

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);

This code prints out the following:

Before async method call id: 257
Before async method call auth: True
After async method call id: 268
After async method call auth: False

Note that the main thread is now unauthenticated after await call. However, if I use ConfigureAwait(false) like below:

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);

I see below output:

Before async method call id: 268
Before async method call auth: True
After async method call id: 242
After async method call auth: True

My understanding on ConfigureAwait(false) is that the code runs in a different thread without knowing the context of original thread (authentication etc.). Hence, it is most suitable for third party libraries.

From above observation, I have below questions -

  1. The thread Id's change before and after the async call. Shouldn't it resume on the main thread calling async method?
  2. Even if the calls resume on different thread (like in the example), shouldn't it resume with the same context of main thread (i.e. IsAuthenticated must be true)? Why does the authentication maintains true with ConfigureAwait(false) and not otherwise?

Thanks!

1

1 Answers

0
votes

A particular threads are not important in ASP.NET. Requests are served by any available thread from the thread pool.

What is important is the synchronization context.

ConfigureAwait(false) instructs the compiler generated state machine to schedule continuations to the thread pool instead of posting them to the captured synchronization context, if one was captured.

It's the synchronization context that sets up the schedule thread pool thread with the proper thread data and thread statics.

You should not invoke ConfigureAwait(false) on action methods because you can't guarantee that that thread data is what you expected.

Despite having a synchronization context or not, async code flows the logical call context across threads. And, with that, flows the current principal.