log4net.ThreadLogicalContext和log4net.ThreadContext之间有什么区别

时间:2010-12-22 09:54:48

标签: log4net

我不理解官方文件中的解释:

逻辑线程可以从一个托管线程跳转到另一个托管线程。

ThreadContext和ThreadLogicalContext之间有什么不同? 有人可以详细说明吗?

感谢。

2 个答案:

答案 0 :(得分:5)

我应该回去把它添加到我自己的问题中(上面链接的Stefan Egli)......

据我所知,两者之间的实际差别很小。

ThreadContext将信息存储在使用Thread.SetData存储的Dictionary中。

ThreadLogicalContext将其信息存储在使用CallContext存储的Dictionary中。

存储在CallContext中的信息几乎相同 可访问性作为使用Thread.SetData存储的信息。也就是说,信息是对首先存储信息的线程的访问。

现在,如果ThreadLogicalContext使用了CallContext.LogicalSetData(或者如果使用CallContext.SetData存储的Dictionary实现了标记接口,IThreadAffinative)那么那将会有很大的不同。在这种情况下,存储的任何信息(LogicalSetData)都可以在同一个线程中访问,并传递给子线程。另外(与逻辑线程一起流动), 信息可以通过远程调用和跨AppDomains流动(如果数据是可序列化的)。

我会提供一些链接,但我在iPhone上工作,所以有点尴尬。 Stefan Egli在上面发布的链接中有一些很好的链接。

另外,请查看9月份Jeffrey Richter撰写的关于CallContext.LogicalSetData的文章。我使用他的测试程序作为比较CallContext.SetData和CallContext.LogicalSetData与Thread.SetData vs [ThreadStatic]的基础。我上次检查时,它是最后一次 他发布的东西。

当我可以轻松访问计算机时,会尝试返回并发布更多链接和/或一些示例代码。

祝你好运!

答案 1 :(得分:3)

自己使用这个,我看到在使用多线程逻辑(asyncawait)时使用ThreadLogicalContext的好处。

例如,如果使用ThreadContext在原始调用线程上设置属性,则它也可用于在同一线程上运行的任何其他任务。

// caller thread (thread #1)
log4net.ThreadContext.Properties["MyProp"] = "123"; // now set on thread #1
log("start");
await Task.WhenAll(
  MyAsync(1), // `Issue` if task run on thread #1, it will have "MyProp"
  MyAsync(2)  // `Issue` if task run on thread #1, it will have "MyProp"
);
log("end"); // `Issue` only by random chance will you run on thread #1 again

如果您使用ThreadLogicalContext,它将保留在调用上下文中。

// caller thread (thread #1)
log4net.LogicalThreadContext.Properties["MyProp"] = "123"; // now set on calling context
log("start");
await Task.WhenAll(
    MyAsync(1), // if task run on thread #1, there is no "MyProp"
    MyAsync(2)  // if task run on thread #1, there is no "MyProp"
);
log("end"); // if task run on thread #1, there is no "MyProp"

使用await,您永远无法保证返回到与启动时相同的线程,并且调用上下文将发生更改,因此您必须再次设置该属性。

...
log4net.LogicalThreadContext.Properties["MyProp"] = "123";
log("end");