gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 13:36:22 25 4
gpt4 key购买 nike

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

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

class Program
{
static void Main(string[] args)
{
var dispatcher = new MessageDispatcher();

//Logical call context data not set yet
Console.WriteLine($"Main: {Thread.CurrentThread.ManagedThreadId}: {CallContext.LogicalGetData("myvar")}"); // Main logical call context data is not set yet = Null
dispatcher.Broadcast("a string"); // logical call context data is still not set yet = Null

//Logical call context data is set now
CallContext.LogicalSetData("myvar", "Logical call context variable");
Console.WriteLine($"Main: {Thread.CurrentThread.ManagedThreadId}: {CallContext.LogicalGetData("myvar")}"); // Main logical call context data is set = return value

dispatcher.Broadcast("a string"); // Logical call context data is set and should return the data set above?

Console.ReadLine();
}
public class MessageDispatcher
{
private readonly ConcurrentQueue<string> _messages;
private readonly AutoResetEvent _waitHandle;
private bool _terminate;
private bool _messageMonitoringActive;

public MessageDispatcher()
{
_messages = new ConcurrentQueue<string>();
_waitHandle = new AutoResetEvent(false);

var thread = new Thread(MonitorCollection);
thread.Start();
}

public void Broadcast(string message)
{
_messages.Enqueue(message);
_waitHandle.Set();
}

private void MonitorCollection()
{
_waitHandle.WaitOne();

string message;
while (_messages.TryDequeue(out message))
{
Console.WriteLine(
$"{message}: {Thread.CurrentThread.ManagedThreadId}: {CallContext.LogicalGetData("myvar")}");
}
}
}
}

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

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

最佳答案

MSDN documentation指出

CallContext is a specialized collection object similar to a Thread Local Storage for method calls and provides data slots that are unique to each logical thread of execution. The slots are not shared across call contexts on other logical threads. Objects can be added to the CallContext as it travels down and back up the execution code path, and examined by various objects along the path.

还有那个

All methods in CallContext are static and operate on the call context in the current Thread.

仅通过阅读文档,您就会认为这种情况是行不通的。 SetDataGetData 方法也是如此;如果您在一个线程上使用 SetData,则必须在同一线程上使用 GetData 才能取回数据。

不过有一个异常(exception); SetLogicalDataGetLogicalData,您已经在使用它们。这些旨在通过“逻辑线程”传递上下文,即跨越同一线程到子线程。

您的方法的问题在于,您试图在子线程创建并启动后 传递数据,这是行不通的。如果你移动

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

以上

var dispatcher = new MessageDispatcher();

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

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

关于c# - 为什么逻辑调用上下文不跨线程传播?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34520156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com