C# CallContext.LogicalGetData()vs ThreadLocal/ThreadStatic

C# CallContext.LogicalGetData()vs ThreadLocal/ThreadStatic,c#,async-await,task-parallel-library,thread-local,C#,Async Await,Task Parallel Library,Thread Local,我目前使用Threadlocal保存当前用户的id,以便根据每个用户的web请求在整个应用程序中使用。在较低的环境中,我无法访问HttpContext,但希望访问静态用户标识,而不将其作为参数传递到任何地方。 最近,我通过async/await添加了并行操作。这不再能保证我在每个任务中都有正确的值。 我在.NET4.6中研究并发现了异步本地,但目前仅限于.NET4.5.1。另一种选择是,CallContext.LogicalGet/SetData()是否能够实现我想要的目标 是的,逻辑调用上下文

我目前使用
Threadlocal
保存当前用户的id,以便根据每个用户的web请求在整个应用程序中使用。在较低的环境中,我无法访问
HttpContext
,但希望访问静态用户标识,而不将其作为参数传递到任何地方。 最近,我通过
async/await添加了并行操作。
这不再能保证我在每个
任务中都有正确的值。


我在
.NET4.6
中研究并发现了
异步本地
,但目前仅限于
.NET4.5.1
。另一种选择是,
CallContext.LogicalGet/SetData()
是否能够实现我想要的目标

是的,逻辑调用上下文将作为异步本地调用

AsyncLocal
在完整的.NET框架上使用逻辑调用上下文-它只是有一个更好的API,可以与即将推出的.NET核心平台一起使用,而逻辑调用上下文不会

记住,正如我在博客上描述的那样


此外,异步本地值对性能也有一定的影响。几乎可以肯定,显式传递参数会更有效,可能是作为您自己的
RequestContext
类型的一部分。ASP.NET vCore正在从HttpContext.Current中移出;它仍然有
HttpContext
的概念,但它不再充当异步本地,而是显式传递。

最好传递该参数。你的设计太复杂了。@Maxim:你确定吗?我怀疑
AsyncLocal
会比
CallContext.Logical*
慢5倍。我昨天用20个作业(Parallel.ForEach)测试了它。。在10个线程上运行(通过线程ID进行实验检测)。。。每个作业都有1000万次迭代的“for”循环,每个循环迭代获得AsyncLocal/CallContext值并将递增值设置回原位。AsyncLocal/CallContext的结果分别为50秒和10秒(大约)。@Maxim:4微秒的差异通常并不重要。测量这么小的时间也有很多固有的问题。测量时间没有任何问题。我使用了整个流程从开始到结束的总时间(模拟100%CPU负载的多线程工作)。因此,它可以与不同IoC容器的性能差异进行比较…@StephenCleary我可以确认它的速度要慢得多,它还产生大量内存流量。