2011-04-15 59 views
2

我試圖通過跟蹤某種我們定義的環境上下文來增強我們的服務器平臺。每個上下文都至少有一個ID,隨着功能流程的進展,我們的平臺的各個部分可能會或可能不會使用該ID。在上下文中,可能會創建線程(或異步調用,或者在其他線程上執行的WF等)。我希望這些子線程能夠參與父項的上下文,至少可以獲得ContextID。從線程到任何子線程的環境數據流

我想象類似如下:

using (Context ctx = Context.Create()) { 
    Log.Print(Context.Current.ID); 
    Task task = Task.Factory.StartNew(() => { 
     Log.Print(Context.Current.ID); 
     using (Context ctx2 = Context.Current.CreateChild()) { 
      Log.Print(Context.Current.ID); 
     } 
     ... 
    } 
    ... 
    task.Wait(); 
} 

那麼應該被印刷是一樣的東西:

「ContextID1」

「ContextID1」

「ContextID1: ContextID2「

幫助在許多服務器上跟蹤日誌消息的主要目的比我們現在的要容易得多。程序和數據在很多(數百臺)機器之間流動,從一個到另一個機器跟蹤太繁瑣。使用環境相關器會非常有幫助,我現在唯一的問題是我不知道子線程如何自動找出父線程的上下文,更不用說訪問它的TLS。如果我能得到父親thead的ManagedThreadID,我可以按照我想要的方式使整個事情工作。

我意識到我可以在創建線程/任務時將上下文作爲開始參數傳遞,但在我們的平臺中有數百萬行代碼,我不能只做出更改。所以要將它烘焙到核心框架中並使其完美環境將解決問題,我確實能夠控制這一點。

回答

1

我一直在設計這樣一個系統,我必須用定製包裝來代替所有與線程啓動相關的代碼,這些代碼將泛化和抽象出上下文鏈接。不幸的是,我不知道有一個很好的透明機制可以解決它。

您最有可能面臨的問題之一是在線程池上執行代碼並要求它繼承父上下文。這裏你需要考慮重用線程池線程的事實。在線程池線程上執行的每項工作都必須優雅地處理上下文繼承,而不會影響未來將在同一線程上執行的任何不相關的代碼片段。