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我可以确认它的速度要慢得多,它还产生大量内存流量。