问题 在IIS中管理后台线程有哪些最佳实践?


我写了一个HttpModule,它产生了一个后台线程。我正在使用线程,就像在进程中运行的Scheduled Task一样,这非常方便。

跟踪此主题的最佳做法是什么?我以前从未这样做过,而且我对它的某些方面感到有些困惑:

  1. 我怎么知道线程是否仍在运行?我认为它可以完成它的工作,但还有另一种方法可以知道它是否还活着吗?我下载了ProcMon,但w3wp.exe产生了一个 勿庸置疑 线程,所以我不知道我的线程是什么。我把它命名为,但这没有用。

  2. 如果线程死了怎么“抓住”线程?是否有某种Dispose方法,我可以让它写入EventLog或其他东西,如果它失败?一个“垂死的宣言”还是什么?

  3. 如何主动停止线程?如果我希望它停止运行此后台进程,如何在不必退回IIS的情况下将其终止?

  4. 无论如何都要重新启动它,独立于HttpModule? (我猜这个问题的答案是否定的......)

编辑: 只是为了澄清,目的是我的线程永远不会消失。它运行一个函数,然后进入睡眠状态几分钟,然后唤醒并再次运行该函数。它不像是在完成一项任务然后结束。


12212
2018-03-17 16:33


起源

你收到system.timeout错误了吗? - TStamper
漠视。这不适用于此 - TStamper


答案:


根据我的经验,你可以让这个工作“足够好”,但并不完美。我建议在Windows服务中实现重复任务。根据任务的作用,Windows服务可能甚至不必与Web应用程序通信,反之亦然,例如, G。如果两者都使用相同的数据库。否则你仍然可以使用e。 G。 WCF用于通信。

最大的优点是:Windows服务将从操作系统开始,您可以使用控制面板轻松配置,启动和停止它,您可以通过Windows事件日志进行内置监控,您可以独立更新后台服务和Web应用程序等等

如果这不是一个选项,e。 G。因为您处于共享托管环境中,我建议您使用以下内容:

  1. 在Application_start(Global.asax)中启动后台线程,并将线程引用存储在静态变量中。
  2. 使用try / catch包装在后台线程上调用的每个方法,因为从.NET 2.0开始,后台线程上的每个未处理的异常都将关闭应用程序。 (它将在下一个请求中重新启动,但它会减慢下一个请求,终止所有当前会话和缓存,当然在下一个请求之前没有计时器将处于活动状态。)
  3. 在每个请求(实现有HttpModule或再次在Global.asax中),检查全局变量中的Thread实例(它仍然是!= null,线程是否活动并正在运行等)。如果没有,请调用重启代码。在重启部分中使用锁定以确保不会同时创建两次线程。

即使这样,如果您没有全天候的常规流量,也无法确定您的后台线程是否始终在运行。另请注意,在共享托管环境中,如果几小时内没有活动,则关闭应用程序池是很常见的。您可以尝试通过在您自己的网络上的客户端计算机上设置计划任务来每隔几分钟在您的应用程序上执行轻量级HTTP请求,以确保您的应用程序始终运行,从而改进这一点。


6
2018-03-17 17:16





当Jeff创建Stackoverflow时,他有一个类似的问题。

他的解决方案是使用缓存过期。你将一些东西放在缓存中,然后当它到期时,在非面向用户的线程中触发一个事件。在到期事件处理程序中,您可以粘贴一些代码以将项目重新添加到缓存中,并为您的应用程序执行任何需要管理的工作

使用此技术,您的子问题很容易回答:

  1. 你检查项目是否仍在 缓存。
  2. 如果该项目不在     缓存,重新添加它。
  3. 去除     缓存中的缓存项。
  4. 加     该项目返回缓存。

您可以创建一个小型管理页面来配置这些选项。

这为您提供了一种在Web应用程序中大致计算内务处理流程的好方法。它不需要单独的Windows服务,这是一个巨大的胜利。


9
2018-03-17 17:27