2011-04-15 33 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

我一直在设计这样一个系统,我必须用定制包装来代替所有与线程启动相关的代码,这些代码将泛化和抽象出上下文链接。不幸的是,我不知道有一个很好的透明机制可以解决它。

您最有可能面临的问题之一是在线程池上执行代码并要求它继承父上下文。这里你需要考虑重用线程池线程的事实。在线程池线程上执行的每项工作都必须优雅地处理上下文继承,而不会影响未来将在同一线程上执行的任何不相关的代码片段。