【问题标题】:What are some best practices for managing background threads in IIS?在 IIS 中管理后台线程有哪些最佳实践?
【发布时间】:2010-10-13 21:22:49
【问题描述】:
我编写了一个产生后台线程的 HttpModule。我正在使用线程,就像在进程中运行的计划任务一样,这真的很方便。
跟踪此线程的最佳做法是什么?我以前从未这样做过,我对它的某些方面有些困惑:
我如何知道线程是否仍在运行?我看到它完成了它的工作,但是还有其他方法可以知道它是否还活着?我下载了 ProcMon,但 w3wp.exe 产生了 boatload 线程,所以我不知道哪个是我的线程。我给它起了名字,但这没有帮助。
如果线程死亡,我如何“抓住”线程?是否有某种 Dispose 方法可以让它写入 EventLog 或者如果它失败了? “垂死宣言”之类的?
如何主动停止线程?如果我想让它停止运行这个后台进程,如何在不反弹 IIS 的情况下杀死它?
是否可以独立于 HttpModule 重新启动它? (我猜这个答案是否定的……)
编辑: 澄清一下,目的是我的线程永远不会消失。它运行一个函数,然后进入睡眠状态几分钟,然后唤醒并再次运行该函数。不是做完一件事就结束了。
【问题讨论】:
标签:
asp.net
multithreading
httpmodule
【解决方案1】:
当 Jeff 制作 Stackoverflow 时,他遇到了类似的问题。
他的解决方案是使用缓存过期。您将某些内容放入缓存中,然后当它过期时,会在非面向用户的线程中触发一个事件。在过期的事件处理程序中,您插入一些代码以将项目重新添加到缓存中,并为您的应用程序执行任何需要完成的内务工作
使用这种技术,您的子问题很容易得到回答:
- 您检查该项目仍在
缓存。
- 如果项目不在
缓存,重新添加。
- 删除
从缓存中缓存项目。
- 添加
将项目返回缓存。
您可以制作一个小的管理页面来配置这些选项。
这为您提供了一种在 Web 应用程序中粗略计时内务处理的好方法。它不需要单独的 Windows 服务,这是一个巨大的胜利。
【解决方案2】:
根据我的经验,你可以让它“足够好”,但并不完美。我建议在 Windows 服务中实现您的重复任务。根据任务的作用,Windows 服务可能甚至不必与 Web 应用程序对话,反之亦然,例如。 G。如果两者都使用同一个数据库。否则你仍然可以使用 e。 G。用于通信的 WCF。
最大的好处是:windows服务将随操作系统启动,您可以使用控制面板轻松配置、启动和停止它,通过Windows事件日志内置监控,您可以更新后台服务和web应用程序独立等。
如果这不是一个选项,例如。 G。因为您处于共享托管环境中,所以我建议您:
- 在 Application_start (Global.asax) 中启动您的后台线程,并将线程引用存储在静态变量中。
- 使用 try/catch 包装后台线程上调用的每个方法,因为从 .NET 2.0 开始,后台线程上的每个未处理异常都会关闭应用程序。 (它将在下一个请求时重新启动,但它会减慢下一个请求,杀死所有当前会话和缓存,当然在下一个请求之前不会有任何计时器处于活动状态。)
- 在每个请求上(实现了一个 HttpModule 或再次在 Global.asax 中),检查全局变量中的 Thread 实例(它是否仍然 != null,线程是否处于活动状态并正在运行等)。如果没有,请调用重新启动代码。在重启部分使用锁定以确保线程不会同时创建两次。
即便如此,如果您没有全天候的正常流量,您也无法确定您的后台线程是否始终在运行。另请记住,在共享托管环境中,如果几个小时内没有活动,关闭应用程序池是很常见的。您可以尝试通过在您自己网络上的客户端计算机上设置计划任务来改善这一点,每隔几分钟对您的应用程序执行一次轻量级 HTTP 请求,以确保您的应用程序始终运行。