对于长时间运行的进程,线程池与自有线程
我们有一些长时间运行的业务流程,这些流程是通过在 WS 2008 R2 上的 IIS(集成模式)中运行的 WCF 服务启动的。这些业务流程通常涉及与我们的 SQL Server 后端的大量交互。我们创建了一个自定义任务队列实现,其中请求通过初始服务调用进行排队,然后根据优先级执行。此执行可能需要很长时间才能完成(最多 20-30 分钟)。然后,客户端可以向服务器查询自己的后台任务的进度。
在我们当前的实现中,任务在单独的线程上触发执行,而不是从线程池中触发。这是由于 阅读建议,不要使用线程池运行长时间运行的任务,以防止 ASP.NET 请求得不到服务。我们通过对可以并发执行的后台任务数量设置上限来控制生成的线程数量。通过这种方式,我们可以尝试控制 CPU 的负载并防止过多的线程上下文切换。尽管所有这些都在发生,我们当然仍然需要满足应用程序的正常“在线”请求。
阅读 这篇文章,作者:Thomas Marquardt 我担心我们没有使用 ThreadPool,因为我们无法从其中内置的调整启发式方法中获益。我们已经通过挂钩 ApplicationEnd 事件并取消长时间运行的任务解决了 Thomas 提到的关闭问题。所以我的问题是,我们应该改用线程池吗?如果这些线索被长期捆绑怎么办?如果我正确理解托马斯,他是说这并不重要,因为线程池会自我调整以创建更多请求来服务正常的在线操作?我还通读了 这个 StackOverflow 问题< /a> 涵盖了相同的理由,但我仍然不确定前进的方向。
We've got some long running business processes that are being initiated through WCF Services running in IIS (integrated mode) on WS 2008 R2. These business processes typically involve lots of interaction with our SQL Server backend. We have created a custom task queue implementation whereby the requests are queued via an initial service call and later executed based on priority. This execution can take long to complete (20-30 minutes extreme). Clients can then query the server for the progress of their own background tasks.
In our current implementation the tasks fires off on a separate thread to execute and not from the ThreadPool. This was done due to reading recommendations of not running long-running tasks using the ThreadPool as to prevent starving the ASP.NET requests from being served. We control the number of threads spawned by placing an upper limit on the number of background tasks that can be executed concurrently. This way we try to control the load on the CPU and prevent too much thread context switching. While all of this is happening we of course still need to serve the normal "on-line" requests for the application as well.
After reading this post by Thomas Marquardt I'm concerned about the fact that we are not using the ThreadPool as we won't get the benefit of the tuning heuristics built into it. We already solve the shutdown issue Thomas mentions by hooking into the ApplicationEnd event and cancelling the long running tasks. So my question is, should we switch over to using the ThreadPool? What about these threads being tied up for lengthy periods of time? If I understand Thomas correctly he is saying this doesn't matter as the ThreadPool will tune itself to create more requests to serve the normal on-line operations? I've also read through this StackOverflow question that covers the same grounds but I'm still unsure as to the way forward.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这并不完全是您所要求的 - 但为什么不在一个单独的进程(例如 Windows 服务)中一起执行长时间运行的任务 - 无论如何,您正在构建一个优先级队列,并且客户端将在一段时间后查询结果。我会采用这种方法,其中前端 WCF 服务对请求进行排队并响应状态更新查询,而后台服务将继续处理请求。这甚至允许工作进程回收等,而无需担心终止当前正在执行的任务。我看到的唯一问题是进程外通信的开销,但与任务所花费的时间相比(因为它们长时间运行),它应该是微不足道的。
This is not exactly what you have asked - but why not execute your long running tasks in a separate process (say windows service) all together - you are anyway building a priority queue and clients are going to query back for results some time later. I would have gone with this approach where front facing WCF Services queues up requests and responds to status update queries while background service would keep serving requests. This would even allow worker process recycles etc w/o worrying about terminating currently executing tasks. Only issue that I see is overhead of out of process communication but then it should be insignificant compared to the time taken by task (as they are long running).
我的建议是避免使用线程池,因为我遇到了您提供的链接中建议的线程饥饿问题。
我们的产品允许用户发起对执行一系列报价的网络服务的调用。这可能是一个长达 40 分钟的长时间运行过程,报价过程是 CPU 密集型的,因此我们使用四核服务器上的线程池来获得最大的 CPU 使用率。
然而,由于 ASP.NET 看起来好像使用线程池来处理请求,因此我们遇到了一个问题,即由于池中缺乏可用线程,用户提交的任何新作业在第一个作业完成之前永远不会开始。为了解决这个问题,我一直在使用我不久前在网上找到的一个名为 ThreadPoolThrottle 的类。这稍微缓解了问题,但随着系统使用量的增长,我们遇到了同样的问题。
我现在正在考虑 VinayC 的建议,即在进程外运行引号,以防止我的 ASP.NET 应用程序中的线程匮乏。
My suggestion is to avoid the ThreadPool as I am having exactly the thread starvation issues suggested in the links you have provided.
Our product allows user to fire off a call to a web service that carries out a series of quotes. This can be a long running process of up to 40 minutes, the quotation process is CPU intensive so, we use the thread pool on our quad core server to gain maximum CPU usage.
However, as ASP.NET looks as if it uses the thread pool to serve requests we have got an issue whereby any new jobs submitted by users never begin until the first job has completed due to the lack of available threads in the pool. To get around this I have been using a class i found on the web a while ago called ThreadPoolThrottle. This has allievated the problems a little bit, but as usage of the system is growing we are running into the same problems.
I am now considering VinayC's suggestion of running the quotes out of process in order to prevent thread starvation in my asp.net app.