【发布时间】:2017-01-24 10:10:40
【问题描述】:
运行下面的代码可以看到 CallContext 和 AsyncLocal 有区别。
using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace AsyncLocalIsDifferentThanCallContext
{
class Program
{
public static AsyncLocal<int> AsyncLocal = new AsyncLocal<int>();
public static int CallContextValue
{
get
{
var data = CallContext.GetData("CallContextValue");
if (data == null)
return 0;
return (int) data;
}
set { CallContext.SetData("CallContextValue", value); }
}
static void Main(string[] args)
{
AsyncLocal.Value = 1;
CallContextValue = 1;
new Thread(() =>
{
Console.WriteLine("From thread AsyncLocal: " + AsyncLocal.Value); // Should be 0 but is 1
Console.WriteLine("From thread CallContext: " + CallContextValue); // Value is 0, as it should be
}).Start();
Console.WriteLine("Main AsyncLocal: " + AsyncLocal.Value);
Console.WriteLine("Main CallContext: " + CallContextValue);
}
}
}
你能解释一下原因吗?
我希望 AsyncLocal 的值在每个线程中都是唯一的,因为 documentation 表示它应该表现得像 CallContext 一样。
【问题讨论】:
-
您为什么期望不同的值?您使用的对象是静态的,因此该对象只能存在 1 个实例。您将此对象的值设置为特定值。然后获取并打印这个值,唯一的事情就是你在不同的线程中做同样的事情。我认为您的期望会因使用静态变量而受到干扰。在此处阅读静态变量:stackoverflow.com/questions/10795502/…
-
我的理解是 AsyncLocal 应该替换 .net 核心上的 CallContext (因为那里没有 CallContext )并且它应该保持线程唯一的值。另请参阅文档链接。
-
您的示例中没有任务,它是基于线程的。
AsyncLocal与您在这里所做的任何事情都无关。 -
使用 LogicalGet/SetData() 代替。虽然目前还不清楚重点可能是什么。
标签: c# multithreading callcontext