我不理解官方文件中的解释:
逻辑线程可以从一个托管线程跳转到另一个托管线程。
ThreadContext和ThreadLogicalContext之间有什么不同? 有人可以详细说明吗?
感谢。
答案 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)
自己使用这个,我看到在使用多线程逻辑(async
,await
)时使用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");