Новые ключевые слова 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 против 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
?
С учетом использования ключевых слов async/await, как лучше всего хранить данные, связанные с конкретным потоком выполнения, которые можно (автоматически!) Восстановить в потоке обратного вызова?
Спасибо,