С новыми ключевыми словами async/wait в C# теперь есть влияние на способ (и когда) вы используете данные ThreadStatic, потому что делегат callback выполняется в другом потоке на один async
началась операция. Например, следующий простой консоли приложение:с использованием переменных ThreadStatic с async/await
[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
ключевые слова?
С использованием ключевых слов async/wait, что лучше всего хранить данные, связанные с конкретным потоком выполнения, который может быть (автоматически!) Восстановлен в потоке обратного вызова?
Спасибо,
Что в случае с WCF? должен ли я просто использовать «OperationContext» вместо этого, при условии, что он будет перенесен на новый поток? – theburningmonk
@ theburningmonk, если вы имеете в виду * экземпляр *, тогда это должно работать. Но я сомневаюсь, что статический 'OperationContext.Current' будет работать правильно. Итак, 'var ctx = OperationContext.Current;' вверху (в исходном потоке), а затем ссылаться только на 'ctx', а не на' OperationContext.Current' –
, поэтому вы говорите, что если вы не захватили текущий 'OperationContext 'в закрытии, как и раньше' await', вы не получите тот же экземпляр 'OperationContext' после' await'? – theburningmonk