我写了一个HttpModule,它产生了一个后台线程.我正在使用线程,就像在进程中运行的预定任务一样,这非常方便.
跟踪此主题的最佳做法是什么?我以前从未这样做过,而且我对它的某些方面感到有些困惑:
我怎么知道线程是否仍在运行?我认为它可以完成它的工作,但还有另一种方法可以知道它是否还活着吗?我下载procmon中,但w3wp.exe的产生一个一大堆的线程,所以我不知道这是我的线程.我命名了,但这没有用.
如果线程死了怎么"抓住"线程?是否存在某种Dispose方法,我可以将其写入EventLog或其他内容,如果它失败了?一个"垂死的宣言"还是什么?
如何主动停止线程?如果我希望它停止运行此后台进程,如何在不必退回IIS的情况下将其终止?
无论如何都要重新启动它,独立于HttpModule?(我猜这个答案是否定的......)
编辑:只是为了澄清,意图是我的线程永远不会消失.它运行一个函数,然后进入睡眠状态几分钟,然后唤醒并再次运行该函数.它不像是在完成一项任务然后结束.
当Jeff创建Stackoverflow时,他有一个类似的问题.
他的解决方案是使用缓存过期.您将某些内容放入缓存中,然后当它过期时,会在非面向用户的线程中触发事件.在到期事件处理程序中,您可以粘贴一些代码以将项目重新添加到缓存中,并为您的应用程序执行任何需要的内务处理工作
使用此技术,您的子问题很容易回答:
您检查该项目是否仍在缓存中.
如果该项目不在缓存中,请重新添加.
从缓存中删除缓存项.
将项目添加回缓存.
您可以创建一个小型管理页面来配置这些选项.
这为您提供了一种在Web应用程序中大致计算内务处理流程的好方法.它不需要单独的Windows服务,这是一个巨大的胜利.
根据我的经验,你可以让这个工作"足够好",但并不完美.我建议在Windows服务中实现重复任务.根据任务的作用,Windows服务甚至可能不需要与Web应用程序通信,反之亦然,例如,如果两者都使用相同的数据库.否则你仍然可以使用例如WCF进行通信.
最大的优点是:Windows服务将从操作系统开始,您可以使用控制面板轻松配置,启动和停止它,您可以通过Windows事件日志进行内置监控,您可以独立更新后台服务和Web应用程序等等
如果这不是一个选项,例如因为您在共享托管环境中,我会建议以下内容:
在Application_start(Global.asax)中启动后台线程,并将线程引用存储在静态变量中.
使用try/catch包装在后台线程上调用的每个方法,因为从.NET 2.0开始,后台线程上的每个未处理的异常都将关闭应用程序.(它将在下一个请求中重新启动,但它会减慢下一个请求,终止所有当前会话和缓存,当然在下一个请求之前没有计时器将处于活动状态.)
在每个请求(实现有HttpModule或再次在Global.asax中),检查全局变量中的Thread实例(它仍然是!= null,线程是否活动并正在运行等).如果没有,请调用重启代码.在重启部分中使用锁定以确保不会同时创建两次线程.
即使这样,如果您没有全天候的常规流量,也无法确定您的后台线程是否始终在运行.另请注意,在共享托管环境中,如果几小时内没有活动,则关闭应用程序池是很常见的.您可以尝试通过在您自己的网络上的客户端计算机上设置计划任务来每隔几分钟在您的应用程序上执行轻量级HTTP请求,以确保您的应用程序始终运行,从而改进这一点.