Lets looks at some simple C# async/await code where I have an object reference (obj
) before and after an await
with ConfigureAwait(false)
private async Task<SomeObject> AnAsyncLibraryMethod(SomeObject obj)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
obj.Name = "Harry"; // <-- obj here
// MAIN POINT
var newSubObj = await FetchOverHttpAsync().ConfigureAwait(false);
// Continuation here
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
obj.Name = "Sally"; // <-- same obj here
return obj;
}
public class SomeObject { public string Name; }
ConfigureAwait(false)
seems to means NOT marshal the continuation back to the original context captured - ok, but what does that really mean? I've tried the code above and obj
IS correctly referenced back (even when it resumes on a different thread).
So the "context" doesn't appear to be the thread's working memory (i.e. thread local storage). So what does "context" contain? Therefore, what does it really mean to
marshal the continuation back to the original context captured
As I describe in my
async
intro blog post, the "context" is:SynchronizationContext.Current
, unless it isnull
, in which case it isTaskScheduler.Current
. Note that if there is no current task scheduler, thenTaskScheduler.Current
is the same asTaskScheduler.Default
, which is a thread pool context.The vast majority of the time, this is either a UI or ASP.NET request context (both types of
SynchronizationContext
), or else it's the thread pool context. Task scheduler contexts seldomly come into play.Note that this context is just used to schedule the continuation. It doesn't do anything with marshaling; in your example
obj
is captured just like it would be if it were referenced from a lambda expression.If I'm not totally wrong,
ConfigureAwait(false);
only means that the code which runs after the code you are awaiting, is not required to use theSynchronizationContext
from before the await.SynchronizationContext
can be different things as Stephen pointed out. So imagine you are in a web environment and your code after the await relies on HttpContext.Current.Items, this might not work anymore if you setConfigureAwait(false);
The following code in an MVC controller would throw an exception for example
Your variable though is simply in the scope of the method and therefor it will be available, basically the method closure/scope, if this makes sense?