CallContext.LogicalGetData 对比。 CallContext.GetData

Posted

技术标签:

【中文标题】CallContext.LogicalGetData 对比。 CallContext.GetData【英文标题】:CallContext.LogicalGetData Vs. CallContext.GetData 【发布时间】:2011-08-31 03:17:23 【问题描述】:

CallContext API 有 LogicalGetDataGetData,但 MSDN 文档并没有解释两者之间的区别以及它们何时不同。

有什么想法吗?

【问题讨论】:

【参考方案1】:

通常,通过CallContext.SetData 存储的数据被认为是线程本地的。也就是说,任何对CallContext.GetData 的调用都会从同一线程获取通过SetData 设置的数据。通过CallContext.LogicalSetData 存储的数据被认为是本地的“逻辑线程”。也就是说,通过CallContext.LogicalSetData 存储的任何数据都将“流向”任何子线程。如果您在同一个线程或任何子线程中调用CallContext.LogicalGetData,您将获得该线程(或父线程)对CallContext.LogicalSetData 的调用所存储的数据。

正如@sixlettervariables 指出的那样,Remoting 和跨 AppDomain 调用也有一些具体的区别(可能跨 AppDomain 意味着 Remoting,我不知道,我对 Remoting 不是很熟悉)。

同样正如@sixlettervariables 所指出的,通过在对象上实现标记接口 ILogicalThreadAffinative,然后使用CallContext.SetData 存储该对象,该对象的行为本质上就好像它已由CallContext.LogicalSetData 存储一样。

这是 Jeff Richter 关于使用 LogicalSetData/LogicalGetData 的一篇很好的博文:

http://www.wintellect.com/CS/blogs/jeffreyr/archive/2010/09/27/logical-call-context-flowing-data-across-threads-appdomains-and-processes.aspx

这里有一些关于 SO 的更多链接,它们可能会更深入地了解 CallContext.SetData/GetData、CallContext.LogicalSetData/LogicalGetData 以及各种形式的线程本地存储:

CallContext vs ThreadStatic

How to Pass a variable to another Thread

【讨论】:

我相信它也会作为ExecutionContext 的一部分在使用 async/await 时在线程之间流动,我假设这种情况也是如此 - Logical[Set|Get]Data 用于非@987654334 @实施者?【参考方案2】:

It appears that this is a subtle difference related to method calls made remotely to another AppDomain。在这种情况下,会创建一个LogicalCallContext,并以LogicalGetData 可访问的方式存储数据。在正常的非远程方法调用中,数据以GetData 可访问的方式存储。

当对另一个 AppDomain 中的对象进行远程方法调用时,CallContext 类会生成一个与远程调用一起传播的 LogicalCallContext 实例。只有公开 ILogicalThreadAffinative 接口并存储在 CallContext 中的对象才会在 LogicalCallContext 中的 AppDomain 之外传播。不支持此接口的对象不会在具有远程方法调用的 LogicalCallContext 实例中传输。

GetData:

CallContext 中检索具有指定名称的对象。

LogicalGetData:

从逻辑调用上下文中检索具有指定名称的对象。

【讨论】:

以上是关于CallContext.LogicalGetData 对比。 CallContext.GetData的主要内容,如果未能解决你的问题,请参考以下文章