With the new async/await keywords in C#, there are now impacts to the way (and when) you use ThreadStatic data, because the callback delegate is executed on a different thread to one the async
operation started on. For instance, the following simple Console app:
[ThreadStatic]
private static string Secret;
static void Main(string[] args)
{
Start().Wait();
Console.ReadKey();
}
private static async Task Start()
{
Secret = "moo moo";
Console.WriteLine("Started on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Secret is [{0}]", Secret);
await Sleepy();
Console.WriteLine("Finished on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Secret is [{0}]", Secret);
}
private static async Task Sleepy()
{
Console.WriteLine("Was on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Console.WriteLine("Now on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
}
will output something along the line of:
Started on thread [9]
Secret is [moo moo]
Was on thread [9]
Now on thread [11]
Finished on thread [11]
Secret is []
I've also experimented with using CallContext.SetData
and CallContext.GetData
and got the same behaviour.
After reading some related questions and threads:
- CallContext vs ThreadStatic
- http://forum.springframework.net/showthread.php?572-CallContext-vs-ThreadStatic-vs-HttpContext&highlight=LogicalThreadContext
- http://piers7.blogspot.co.uk/2005/11/threadstatic-callcontext-and_02.html
it seems that frameworks like ASP.Net explicitly migrates the HttpContext across threads, but not the CallContext
, so perhaps the same thing is happening here with the use of async
and await
keywords?
With the use of the async/await keywords in mind, what's the best way to store data associated with a particular thread of execution that can be (automatically!) restored on the callback thread?
Thanks,