HttpContext的线程安全性

5

经过一番搜索,我没有找到任何关于HttpContext线程安全性的权威或决定性信息。

我正在考虑以下情况:

public class AsyncHandler : IAsyncHttpHandler 
{
   void BeginProcessRequest(...)
   {
      // Spawn some tasks in parallel, provide them with current HttpContext as argument.
   }

   void EndProcessRequest(...) {...}
}

我的(输入/输出受限)并行任务希望同时访问HttpContext。

查看各种帖子,似乎这是安全的,但我想要一些实际证据。当然,MSDN 给出了通常的“静态是线程安全的等” ,但这没有什么帮助,除非我假设它不是线程安全的。

我在 StackOverflow 上看到过各种帖子(例如这里,或这里,或 这里),但没有真正回答这个问题。

在 .NET 4.5 中所有异步工作中,如果 HttpContext 不是线程安全的,那么似乎有点奇怪,但是,如果确实如此,是否有任何方法使其线程安全?我可以想到:

  • 克隆它(但这并不容易,尽管乍一看似乎不是不可能的)。
  • 包装 HttpContextBase 并使其线程安全(嘿,我会称之为 HttpContextWrapperWrapper )。

但这一切都感觉有点糟糕,而且太麻烦了。

编辑: 在更详细地研究此问题并进行一些反射后,我认为 HttpContext 确实不是线程安全的并没有关系。我在这篇博客文章中详细介绍了这一点。要点是在 ASP.NET 中使用正确的 SynchronizationContext 可以确保不会同时访问上下文的多个线程。


2
我认为这不是一个清晰明了的情况 - 我认为你需要详细说明你打算执行哪些修改 - 如果多个线程尝试设置/重置同一响应头,我肯定不知道我会期望发生什么。 - Damien_The_Unbeliever
我主要考虑的是读取,比如查询参数,而不是设置头之类的东西。我同意,我不知道我会期望发生什么。同时向响应流写入也没有太多意义。 - Marcus
1个回答

8

HttpContext类不是线程安全的。

例如,HttpContext.Items属性只是对一个未同步的Hashtable的引用 - 所以这显然不是线程安全的。

从您的问题中不清楚您想在并行任务之间共享什么,但我建议您使用自己的线程安全类的实例来共享状态,而不是尝试包装现有类。


简单而令人信服的答案,这似乎确实是正确的方法。尽管Items是IDictionary(因此可能是线程安全的),但它实际上似乎是由一个返回false的IsSynchronized属性的HashTable实现的。 - Marcus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接