2017-05-05 59 views
4

我不得不在我的代码中用AsyncLocal替换ThreadLocal的使用,以便在等待异步操作时维持'环境状态'。为什么AsyncLocal <T>传播到ThreadLocal <T>没有的子线程?

但是,AsyncLocal令人讨厌的行为是它'流'到子线程。这与ThreadLocal不同。无论如何要防止这一点?

class Program 
{ 
    private static readonly ThreadLocal<string> ThreadState = new ThreadLocal<string>(); 
    private static readonly AsyncLocal<string> AsyncState = new AsyncLocal<string>(); 

    static async Task MainAsync() 
    { 
     ThreadState.Value = "thread"; 
     AsyncState.Value = "async"; 

     await Task.Yield(); 

     WriteLine("After await: " + ThreadState.Value); 
     WriteLine("After await: " + AsyncState.Value); // <- I want this behaviour 

     Task.Run(() => WriteLine("Inside child task: " + ThreadState.Value)).Wait(); // <- I want this behaviour 
     Task.Run(() => WriteLine("Inside child task: " + AsyncState.Value)).Wait(); 

回答

6

AsyncLocal存储在执行上下文中的数据,它是由大多数API(包括Task.Run)自动飞行。防止

一种方法是在需要时明确抑制流量:

using (ExecutionContext.SuppressFlow()) 
{ 
    Task.Run(...); 
} 
+0

是否该AsyncLocal数据由Task.Run飞行的事实意味着它应该是“线程安全”?虽然这不是必需的,因为TaskLocal会(并且可能)只能被单个线程访问? – Darragh

相关问题