Shaun Luttin
Shaun Luttin

Reputation: 141682

What state is in the thread that the SynchronizationContext chooses that is not in the IAsyncStateMachine?

When an await happens in an async method, an IAsyncStateMachine preserves "locals" and other necessary state. As far as I can tell, this includes method variables and static/instance variables that the method is using.

When the await happens, it also captures a SynchronizationContext, which determines when, where (on what thread), and in what order the method's re-entry (continuation) occurs. The thread that this context chooses for re-entry will include additional state that the continuation might use.

So not all of the "necessary state" goes into the state machine; some of it is in the thread that the SynchronizationContext chooses for the continuation.

Questions:

  1. What state does the thread contain that the state machine does not?
  2. What are the characteristics of state that goes into the thread versus state that goes into the state machine?

https://blogs.msdn.microsoft.com/pfxteam/2012/04/12/asyncawait-faq/

Upvotes: 0

Views: 260

Answers (1)

Servy
Servy

Reputation: 203825

When an await happens in an async method, the IAsyncStateMachine preserves "locals" and other necessary state. As far as I can tell, this includes method variables and static/instance variables that the method is using.

The state machine does indeed need to keep track of locals (which includes the parameters for the method). It doesn't keep track of any instance variables or static variables. You don't need to put them in the state machine for them to exist after the method ends; they'll continue to exist entirely on their own after the method ends.

When the await happens, it also captures a SynchronizationContext, which determines when, where (on what thread), and in what order the method's re-entry (continuation) occurs.

While this is generally close enough to the truth for the purposes of casual references to it, and hence why many people tend to say this, this isn't quite right, and the subtleties are relevant to this particular question.

SynchronizationContext is just a class, and it has a Post and Send method in which the context is provided a method, and it executes that method in whatever "the context" means for that situation. It can go about executing that delegate however it wants, and there are lots of ways that different contexts go about deciding how to execute that delegate.

For the synchronization context used by a windows forms or WPF application, it means running it in the UI thread's message loop. For an ASP application it means scheduling a thread pool thread to run with a particular requests HttpContext set (while ensuring that no two are running at the same time, even though the same thread may not be used for all operations handling a request). You can also write your own synchronization context that does whatever you want it to do.

The thread that this context chooses for re-entry includes state that the method is uses.

Typically not. The thread-specific state is primarily the data on the stack, which is primarily composed of method parameters and locals, but in the case of the async method the locals and method parameters were all hoisted to fields of the state machine. While it's technically possible that the synchronization context is setting thread-static static fields (and this is in fact happening in the ASP case with HttpContext.Current) it's pretty unusual. Any thread-specific state that is involved in this situation could only be code in the synchronization context, not anything inherent to the async keyword.

What state does the thread contain that the state machine does not?

In the general case for an async method, none. Any data that would normally be stored in thread-specific locations is moved to the state machine so that it is no longer thread specific.

What are the characteristics of state that goes into the thread versus state that goes into the state machine?

All of it goes into the state machine if it would otherwise be specific to that thread.

Upvotes: 4

Related Questions