2017-05-05 18 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

相關問題