在ASP.NET中的一个高流量的情况下使用ThreadPool.QueueUserWorkItem [英] Using ThreadPool.QueueUserWorkItem in ASP.NET in a high traffic scenario

查看:109
本文介绍了在ASP.NET中的一个高流量的情况下使用ThreadPool.QueueUserWorkItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在IM pression下,使用线程池的(假设非关键)短命的后台任务被认为是最佳做法,即使是在ASP.NET,但后来我碰到<少时HREF =htt​​p://csharpfeeds.com/post/5415/Dont%5Fuse%5Fthe%5FThreadPool%5Fin%5FASP.NET.aspx>这似乎并非如此这篇文章 - 的说法是,你应该离开线程池来处理ASP.NET相关的请求。

I've always been under the impression that using the ThreadPool for (let's say non-critical) short-lived background tasks was considered best practice, even in ASP.NET, but then I came across this article that seems to suggest otherwise - the argument being that you should leave the ThreadPool to deal with ASP.NET related requests.

因此​​,这里是如何我一直在做小的异步任务至今:

So here's how I've been doing small asynchronous tasks so far:

ThreadPool.QueueUserWorkItem(s => PostLog(logEvent))

文章是建议而不是建立一个螺纹明确,类似于:

And the article is suggesting instead to create a thread explicitly, similar to:

new Thread(() => PostLog(logEvent)){ IsBackground = true }.Start()

第一种方法中的管理和界定的优势,但有潜在的(如果文章是正确的)的后台任务,然后争夺与ASP.NET请求处理线程。第二种方法释放了线程池,但被无限的,因此成本可能用起来太多的资源。

The first method has the advantage of being managed and bounded, but there's the potential (if the article is correct) that the background tasks are then vying for threads with ASP.NET request-handlers. The second method frees up the ThreadPool, but at the cost of being unbounded and thus potentially using up too many resources.

所以我的问题是,在文章中的建议是否正确?

So my question is, is the advice in the article correct?

如果您的网站获得这么多的流量,你的线程池快满了,那么是不是更好地走出去带外,或将一个完整的线程池意味着你得到你的资源的限制,无论如何,在你不应该试图这种情况下,开始自己的线程?

If your site was getting so much traffic that your ThreadPool was getting full, then is it better to go out-of-band, or would a full ThreadPool imply that you're getting to the limit of your resources anyway, in which case you shouldn't be trying to start your own threads?

澄清:我只是要求在小非关键异步任务(如远程登录),不贵的工作项目,将需要一个单独的进程(在这些情况下,我同意你需要一个更强大的范围溶液)。

Clarification: I'm just asking in the scope of small non-critical asynchronous tasks (eg, remote logging), not expensive work items that would require a separate process (in these cases I agree you'll need a more robust solution).

推荐答案

在这里其他的答案似乎离开了最重要的一点:

Other answers here seem to be leaving out the most important point:

除非你试图以并行CPU密集型操作来完成它在低负载的网站速度快,有使用工作线程都没有任何意义。

这也适用于既有免费主题,由新的Thread(...)中,与工作线程线程池,为 QueueUserWorkItem 的请求。

That goes for both free threads, created by new Thread(...), and worker threads in the ThreadPool that respond to QueueUserWorkItem requests.

是的,这是真的,你的可以的由排队太多工作项目饿死线程池在ASP.NET进程。它将从处理其他请求prevent ASP.NET。本文中的信息在这方面是准确的;用于 QueueUserWorkItem 相同的线程池也被用来服务请求。

Yes, it's true, you can starve the ThreadPool in an ASP.NET process by queuing too many work items. It will prevent ASP.NET from processing further requests. The information in the article is accurate in that respect; the same thread pool used for QueueUserWorkItem is also used to serve requests.

但如果你实际上是在排队足够的工作项目,使这个饥饿,那么你的 的应该是饥饿的线程池!如果你是在同一时间运行字面上数百个CPU密集型操作,它会做什么好事,有另一个工作线程服务ASP.NET请求,当机器已经超载?如果你正在运行到这个情况,你需要完全重新设计!

But if you are actually queuing enough work items to cause this starvation, then you should be starving the thread pool! If you are running literally hundreds of CPU-intensive operations at the same time, what good would it do to have another worker thread to serve an ASP.NET request, when the machine is already overloaded? If you're running into this situation, you need to redesign completely!

大多数我看到或听到关于多线程code暂且在ASP.NET使用不当,它不是排队CPU密集型的工作。这对排队的I / O密集​​型的工作。和如果你想要做的I / O工作,那么你就应该使用I / O线(I / O完成端口)。

Most of the time I see or hear about multi-threaded code being inappropriately used in ASP.NET, it's not for queuing CPU-intensive work. It's for queuing I/O-bound work. And if you want to do I/O work, then you should be using an I/O thread (I/O Completion Port).

具体而言,您应该使用以任何库类,你正在使用支持异步回调。这些方法总是很清楚地标示;他们开始的话开始结束。正如 Stream.BeginRead Socket.BeginConnect WebRequest.BeginGetResponse ,等等。

Specifically, you should be using the async callbacks supported by whatever library class you're using. These methods are always very clearly labeled; they start with the words Begin and End. As in Stream.BeginRead, Socket.BeginConnect, WebRequest.BeginGetResponse, and so on.

这些方法的的使用线程池,但他们使用IOCPS,该做的不可以干扰ASP.NET要求。它们是一种特殊的轻量线程的通过从I / O系统的中断信号可以被唤醒起来。而在ASP.NET应用程序中,通常有一个I /每个工作线程O线程,因此每一个请求可以有一个异步操作排队。这是数以百计的异步操作没有任何显著的性能下降(假设I / O子系统能够跟上)。它的方式超过你所需要的。

These methods do use the ThreadPool, but they use IOCPs, which do not interfere with ASP.NET requests. They are a special kind of lightweight thread that can be "woken up" by an interrupt signal from the I/O system. And in an ASP.NET application, you normally have one I/O thread for each worker thread, so every single request can have one async operation queued up. That's literally hundreds of async operations without any significant performance degradation (assuming the I/O subsystem can keep up). It's way more than you'll ever need.

只要记住,异步的代表的不以这种方式工作 - 他们最终会使用一个工作线程,就像 ThreadPool.QueueUserWorkItem 。这只是内置的.NET Framework库类,有能力这样做的异步方法。你可以自己做,但它是复杂的,有点危险,可能超出了本文讨论的范围。

Just keep in mind that async delegates do not work this way - they'll end up using a worker thread, just like ThreadPool.QueueUserWorkItem. It's only the built-in async methods of the .NET Framework library classes that are capable of doing this. You can do it yourself, but it's complicated and a little bit dangerous and probably beyond the scope of this discussion.

最好的回答了这个问题,在我看来,是的不使用线程池 背景在ASP.NET主题实例的。这一点也不像在Windows纺一个线程窗体应用程序,你这样做是为了保持UI响应并不在乎它是多么高效。在ASP.NET中,你关注的是的吞吐量的,所有这方面的所有工作线程切换是绝对要去的的你吞吐量是否使用线程池或没有。

The best answer to this question, in my opinion, is don't use the ThreadPool or a background Thread instance in ASP.NET. It's not at all like spinning up a thread in a Windows Forms application, where you do it to keep the UI responsive and don't care about how efficient it is. In ASP.NET, your concern is throughput, and all that context switching on all those worker threads is absolutely going to kill your throughput whether you use the ThreadPool or not.

请,如果你发现自己正在用ASP.NET线程code - 考虑是否可以改写使用pre-现有的异步方法,如果不能,那么请考虑是否或者不是你真的,真的需要code到在后台线程运行的。在大多数情况下,你可能会因为没有净效益增加复杂性。

Please, if you find yourself writing threading code in ASP.NET - consider whether or not it could be rewritten to use pre-existing asynchronous methods, and if it can't, then please consider whether or not you really, truly need the code to run in a background thread at all. In the majority of cases, you will probably be adding complexity for no net benefit.

这篇关于在ASP.NET中的一个高流量的情况下使用ThreadPool.QueueUserWorkItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆