asp.net - HttpApplication 事件改变线程

标签 asp.net .net multithreading

出于 ASP.NET Web 应用程序的日志记录目的,我将一些状态信息保存在静态类中。这些字段被标记为[ThreadStatic],因此每个线程都有自己的字段副本。日志记录方法是从 HttpApplication 事件方法调用的:

  • Application_BeginRequest(请求开始,初始化状态)
  • Application_AcquireRequestState( session 和用户已知)
  • Application_EndRequest(请求结束,清理)

我现在可以观察到,在某些情况下,页面请求是在不同的线程中处理的。 BeginRequest 事件在线程 18 上运行,而以下事件在线程 4 上运行。当然,我的线程静态数据将不可用,并且会发生错误。

大多数情况下,这工作得很好,每个请求仅在单个线程中处理。但是,当我请求加载约 5 秒的页面并在 1-2 秒后单击另一个链接时,两个请求并行运行。第一个请求在 5 秒后在线程 24(它也在线程 24 上启动)上完成,而另一个请求在线程 18 上启动,但在第一个请求完成后,第二个请求继续在线程 4 上运行。

尝试使用 3 个重叠的长请求,这纯粹是困惑。我什至可以观察在同一线程上启动的两个请求,而它们随后在不同的线程上继续。请求和线程之间似乎没有任何关系。

请求怎么会改变线程呢?如果它决定转移到另一个线程,它就会丢失所有状态。我能找到的每个描述都表明这一切都发生在单个线程中。

IIS 7、Windows Server 2008 R2、x64 上的 ASP.NET 4.0。

替代方案:如果我不能依赖从开始到结束仅在单个线程中处理请求,那么存储少量每个请求数据的最佳位置是什么(目前一个整数和一个类),访问速度非常快?并且最好在不引用 System.Web 的情况下也能工作(我的代码也针对客户端配置文件)。我知道 HttpContext.Current.Items[key] 但它在远程处理程序集的深处查找,并且涉及一个字典,它看起来比线程静态字段慢很多。

最佳答案

ASP.NET 是 thread agile并且一个请求可以在多个线程上处理(但一次不能超过一个)。因此,您确实无法在 ASP.NET 中使用 ThreadStatics。但是,您可以安全地使用 HttpContext.Items 字典来存储需要限制为单个请求的内容。

要允许您的代码在 ASP.NET 应用程序的上下文之外工作,您可以创建一个交换 HttpContext/CallContext 的包装器,具体取决于代码所在的环境。Here is an example of such a wrapper .

关于asp.net - HttpApplication 事件改变线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24083360/

相关文章:

java - 计算移动平均值的线程安全方法

javascript - 如何使用asp.net c#将使用jsPDF生成的PDF附加到邮件中

c# - 用户在 ASP.NET 中为 YAF 选择了 theme.css

c# - WPF 中的 MVVM - 如何提醒 ViewModel 模型中的变化......或者我应该吗?

c++ - 文件属性对话框中的自定义选项卡

Java 8+ ConcurrentHashMap 锁 strip 化

c# - ASP.NET 5 Identity 3 用户在应用程序重启后注销

javascript - 在特定的 div 中获取检查的输入值 - 简单的 jquery 问题

.net - PowerShell - 将特定文件压缩到文件夹中

java - Java.util.concurrent 库是否比标准的 Android AsyncTask 更擅长执行任何类型的任务