为什么逻辑调用上下文不跨线程传播?

时间:2015-12-29 22:33:04

标签: c# .net multithreading

我有一个奇怪的问题,逻辑调用上下文没有传播到我的应用程序中的线程。

在此示例中,线程(在设置逻辑调用上下文数据之前创建)不会获取新值:

clip

对于在创建的线程内进行的所有调用,不会从刚刚设置的上下文变量中采用调用上下文数据。那是为什么?

在我的应用程序中,我无法在实例化时设置逻辑调用上下文变量(这是在启动时通过IoC完成的(它是WebAPI堆栈)),但仅限于每次调用。

2 个答案:

答案 0 :(得分:10)

MSDN documentation表示

  

CallContext是一个专门的集合对象,类似于方法调用的线程本地存储,并提供对每个逻辑执行线程唯一的数据槽。插槽不在其他逻辑线程上的调用上下文之间共享。可以将对象添加到CallContext中,因为它向下移动并备份执行代码路径,并通过路径上的各种对象进行检查。

还有那个

  

CallContext中的所有方法都是静态的,并且在当前Thread中的调用上下文中运行。

只是阅读文档,您认为这种情况不起作用。 SetDataGetData方法也是如此;如果在一个线程上使用SetData,则必须在同一个线程上使用GetData才能恢复数据。

但是有一个例外;您已使用的SetLogicalDataGetLogicalData。它们旨在通过“逻辑线程”流动上下文,即通过相同的线程到子线程。

您的方法存在的问题是,在创建并启动子线程后,您尝试传递数据,这将无效。如果你移动

CallContext.LogicalSetData("myvar", "Logical call context variable");

以上

var dispatcher = new MessageDispatcher();

即。在创建并启动线程之前(在MessageDispatcher构造函数中)。你会看到你正确地获得了价值。

换句话说;在创建和启动子线程之前,您需要确保已设置所有数据。

答案 1 :(得分:-1)

来自https://msdn.microsoft.com/library/w61s16a1(v=vs.100).aspx

  

CallContext的作用域是线程。有一个单独的CallContext   应用程序中运行的每个线程的对象