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

发布于 2024-07-15 09:18:08 字数 601 浏览 5 评论 0原文

我编写了一个生成后台线程的 HttpModule。 我使用该线程就像在进程中运行的计划任务一样,这非常方便。

跟踪该线程的最佳实践是什么? 我以前从未这样做过,并且对它的某些方面有点困惑:

  1. 我如何知道线程是否仍在运行? 我看到它完成了它的工作,但是还有其他方法可以知道它是否还活着吗? 我下载了 ProcMon,但是 w3wp.exe 生成了一大堆线程,所以我不知道哪个是我的线程。 我给它命名了,但这没有帮助。

  2. 如果线程死了,我该如何“捕获”该线程? 是否有某种 Dispose 方法,如果失败,我可以将其写入 EventLog 或其他内容? “死亡声明”或其他什么?

  3. 如何主动停止线程? 如果我希望它停止运行这个后台进程,我该如何杀死它而不需要反弹 IIS?

  4. 有没有办法独立于 HttpModule 再次启动它? (我猜答案是否定的...)

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

I have written an HttpModule that spawns a background thread. I'm using the thread like a Scheduled Task that runs in-process, which is really handy.

What are best practices for keeping track of this thread? I've never done this before, and I'm a little confused about some aspects of it:

  1. How do I know if the thread is still running? I see it do its job, but is there another way to know if it's still alive? I downloaded ProcMon, but w3wp.exe spawns a boatload of threads, so I had no idea which was my thread. I named it, but that didn't help.

  2. How do I "catch" the thread if it dies? Is there some kind of Dispose method where I can have it write to the EventLog or something if it fails? A "dying declaration" or something?

  3. How do I actively stop the thread? If I want it to stop running this background process, how do I kill it without having to bounce IIS?

  4. Is there anyway to start it again, independently of the HttpModule? (I'm guessing the answer to this is no...)

Edit: Just to clarify, the intention is that my thread never goes away. It runs a function, then goes to sleep for a couple minutes, then wakes up and runs the function again. It's not like it's doing one task then ending.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城仅有旧梦在 2024-07-22 09:18:08

当 Jeff 创建 Stackoverflow 时,他也遇到了类似的问题。

他的解决方案是使用缓存过期。 您可以将某些内容放入缓存中,然后当它过期时,会在面向非用户的线程中触发一个事件。 在过期的事件处理程序中,您插入一些代码以将项目重新添加到缓存中,并执行应用程序需要完成的任何内务工作

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

  1. 您检查该项目仍然是在
    缓存。
  2. 如果该项目不在
    缓存,重新添加。
  3. 去除
    从缓存中缓存项目。
  4. 添加
    该项目返回到缓存。

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

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

When Jeff made Stackoverflow, he had a similiar issue.

His solution was to use the cache expiration. You'd put something in the cache and then when it expires an event is fired in a non-user facing thread. In the event handler for the expiration, you stick some code in to re-add the item to the cache and do whatever housekeeping work needs to be done for your application

Using this technique, your subquestions are easily answered:

  1. You check the item is still in
    cache.
  2. If the item is not in
    cache, re-add it.
  3. Remove the
    cache item from the cache.
  4. Add
    the item back to the cache.

You could make a small management page to configure these options.

This gives you a nice way to roughly time housekeeping processes in your web-application. It doesn't require a seperate Windows Service, which is a big win.

寄与心 2024-07-22 09:18:08

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

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

如果这不是一个选项,例如因为您处于共享托管环境中,我建议您执行以下操作:

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

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

From my experience, you can get this to work "good enough", but not perfect. I would recommend to implement your repeating tasks in a windows service. Depending on what the tasks do, the Windows Service maybe wouldn't even have to talk to the web application or vice versa, e. g. if both work with the same database. Otherwise you could still use e. g. WCF for communication.

The big advantage is: The windows service will start with the OS, you can easily configure, start and stop it using the control panel, you have built-in monitoring via Windows Event Log, you can update the background service and the web application independently etc.

If this is not an option, e. g. because you are in a shared hosting environment, I would recommend the following:

  1. Start your background thread in Application_start (Global.asax), and store the thread reference in a static variable.
  2. Wrap every method called on your background thread with try/catch, because since .NET 2.0, every unhandled exception on a background thread will shut down the application. (It will be restarted on the next request, but it slows down the next request, kills all current sessions and caches, and of course no timer will be active until the next request.)
  3. On every request (implemented has a HttpModule or in Global.asax again), check the Thread instance in the global variable (is it still != null, is the thread active and running etc.). If not, call the restart code. Use locking in the restart part to make sure that the thread will not be created twice at same time.

Even then you can't be sure that your background thread is always running, if you don't have regular traffic around the clock. Also keep in mind that in a shared hosting environment it is very common to shut down application pools if there is no activity for a few hours. You could try to improve this by setting up a scheduled task on a client machine on your own network doing a light-weight HTTP request on your application every few minutes, just to ensure that your application is always running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文