使用新的 C# async/await 关键字会影响 ThreadStatic 数据的使用方式(以及何时使用),因为回调委托在一个不同的线程上执行,而非 async
操作开始的线程。例如,以下简单的控制台应用程序:
[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);
}
将会输出类似以下内容:
Started on thread [9]
Secret is [moo moo]
Was on thread [9]
Now on thread [11]
Finished on thread [11]
Secret is []
我也尝试使用CallContext.SetData
和CallContext.GetData
,但得到了相同的行为。
阅读了一些相关的问题和线程:
- 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
似乎像ASP.NET这样的框架会明确地在不同线程之间传递HttpContext
,但不会传递CallContext
,所以也许使用async
和await
关键字时发生了同样的事情?
考虑到使用异步/等待关键字,什么是存储与特定执行线程关联的数据并可以在回调线程上(自动!)恢复的最佳方法?
谢谢,