【问题标题】:CallContext.LogicalGetData() vs ThreadLocal/ThreadStaticCallContext.LogicalGetData() 与 ThreadLocal/ThreadStatic
【发布时间】:2016-08-28 19:26:54
【问题描述】:

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

我在.Net 4.6 中研究并发现了AsyncLocal,但目前仅限于.Net 4.5.1。作为替代方案,CallContext.LogicalGet/SetData() 是否能够实现我想要的?

【问题讨论】:

  • 最好传递那个参数。你的设计过于复杂了。

标签: c# async-await task-parallel-library thread-local


【解决方案1】:

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

AsyncLocal<T> 在完整的 .NET 框架上使用逻辑调用上下文 - 它只是具有更好的 API,并且可以与即将推出的 .NET Core 平台一起使用,而逻辑调用上下文则不能。

记得only store immutable data,正如我在我的博客中描述的那样。

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

【讨论】:

  • @Maxim:你确定吗?我怀疑AsyncLocal<T> 会比CallContext.Logical* 慢5 倍。
  • 我昨天用 20 个作业(Parallel.ForEach)对其进行了测试。在 10 个线程上运行(通过线程 ID 进行实验检测)...每个作业都有“for”循环,每个循环都有 1000 万次迭代迭代获取 AsyncLocal / CallContext 值并设置增量值。 AsyncLocal / CallContext 的结果分别为 50 秒和 10 秒(大约)。
  • @Maxim:4 微秒的差异通常无关紧要。测量这么小的时间也有很多固有的问题。
  • 测量时间没有任何问题。我使用了从整个过程开始到结束的总时间(模拟 100% CPU 负载的多线程工作)。所以可以比较不同IoC容器的性能差异...
  • @StephenCleary 我可以确认它要慢得多,它还会产生大量内存流量。
猜你喜欢
  • 2013-08-22
  • 2020-11-10
  • 1970-01-01
  • 2016-10-30
  • 2010-09-21
  • 2014-08-30
  • 2011-08-31
  • 1970-01-01
相关资源
最近更新 更多