【问题标题】:C#: Anything wrong with setting HttpContext.Current in a parallel thread?C#:在并行线程中设置 HttpContext.Current 有什么问题吗?
【发布时间】:2011-10-21 15:16:42
【问题描述】:

我正在使用一个依赖于 HttpContext.Current 的库。该库是 Facebook C# SDK,但我的问题也应该适用于其他场景。我想从并行线程内部使用这个库。但是,HttpContext.Current 在并行线程中不可用,因此我正在考虑将其缓存到局部变量,然后将其设置在并行线程中,如下所示:

var httpContext = HttpContext.Current;
Parallel.ForEach(items, item => {

    try {

        HttpContext.Current = httpContext;

        // Call a method that relies on HttpContext.Current

    } finally {
        HttpContext.Current = null;
    }
});

你预见到这有什么问题吗?这样做有什么后果吗?

【问题讨论】:

  • 你在 httpContext 中究竟使用了什么?例如,如果它只是缓存中的一个值,最好将它传递给每个线程。
  • 在 Reflector 或 ILSpy 中打开它。观察Current 归结为Thread.CurrentThread.GetIllogicalCallContext().HostContext。答案很明显:)
  • 为什么不直接将上下文作为状态传递呢?干净多了
  • 我刚接触到 Facebook C# SDK 代码,看起来它只使用 HttpContext.Current 来确定当前请求是否安全(_httpContext.Request.Url.Scheme)。所以我上面的示例代码确实有效,但可能不是一个好主意?
  • Kevin 和 Marc,你能提供一个例子来说明你的建议吗?不过,我不想更改库代码。谢谢。

标签: c# asp.net multithreading facebook-c#-sdk task-parallel-library


【解决方案1】:

对我来说似乎没问题。使用 try ... finally 也是一个好点,因为线程可以重用,并且您可以使上下文长时间保持活动状态,从而避免垃圾收集。 不要认为有其他方法可以解决这个问题。

但请注意,您调用的 api 不会在此多线程环境中产生问题。 并非所有代码都是线程安全的,执行涉及写入\读取某些缓存值的写入操作或读取操作。

还要注意,如果字段值不是易失性的或未使用 System.Threading.Interlocked,则无法正确和/或及时将字段值从一个线程传播到另一个线程! 这可能会给您带来问题,尤其是在发布版本中。

但是,您可以使用 Thread.MemoryBarrier 或 lock,在网络上搜索这个烦人(但不可避免)的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多