Asp.net 在IIS中使用线程的特殊注意事项

Asp.net 在IIS中使用线程的特殊注意事项,asp.net,iis,Asp.net,Iis,我想开始在IIS中使用异步处理。编辑:我说的是使用任务并行库 例如,在某些页面加载时,我想记录一些废话,发送电子邮件,更新一些表,等等。但我不想让用户等着我记录这些废话 所以通常我做的是我有一个静态队列,我把日志信息推到这个队列上,然后我有一个cron作业,它每10分钟调用一个特殊页面,其OnLoad刷新队列。这是可行的,但是设置起来有点笨重,特别是当你想记录50件事情的时候。我宁愿这样做: Task.CreateNew(() => Log(theStuff)); 然而,我害怕在IIS中

我想开始在IIS中使用异步处理。编辑:我说的是使用任务并行库

例如,在某些页面加载时,我想记录一些废话,发送电子邮件,更新一些表,等等。但我不想让用户等着我记录这些废话

所以通常我做的是我有一个静态队列,我把日志信息推到这个队列上,然后我有一个cron作业,它每10分钟调用一个特殊页面,其OnLoad刷新队列。这是可行的,但是设置起来有点笨重,特别是当你想记录50件事情的时候。我宁愿这样做:

Task.CreateNew(() => Log(theStuff));
然而,我害怕在IIS中运行任务,因为一个错误就会导致整个网站崩溃

所以现在我有了

SafeTask.FireAndForget(() => Log(theStuff));
这会将委托包装在一些try/catch中,并将其传递到Task.CreateNew中。因此,如果有人更改了影响其他内容的内容,并在其他地方生成了异常,而该异常意外地被抛出到任务线程中,我们将收到一个通知,而不是崩溃的网站。此外,catch中的错误通知也在它自己的try/catch中,并且该catch的try/catch也有一个尝试以不同方式登录的try/catch


现在我可以在IIS中安全地异步运行stuff,在开始使用SafeTask类之前,我还需要担心哪些事情呢?

考虑使用页面的OnUnload事件。请在此处阅读:

此事件在内容发送给用户后触发(这样用户在工作时不会被阻止),并且应该完全满足您的要求,而不引入额外的线程


具体到您的问题,只有在负载和性能测试表明您遇到了线程限制时,才应该关注线程池耗尽。如果你不是,那么你的建议当然是合理的。

IIS和.net中的每个请求默认在一个线程中处理。此线程来自一个名为“应用程序池”的线程池。现有线程是重用的,所以除非每次都清除或设置线程状态,否则不能将它们真正用于线程状态。您可以使用machine.config甚至web.config中的MSDN公式来定义此线程池的大小

现在,每个异步函数调用都放在不同的线程上。这包括异步web服务调用、异步页面函数、异步委托等。此线程来自“应用程序池”,因此减少了IIS可用于服务新请求的线程数

在使用异步函数调用时,应用程序很可能工作正常。如果您担心或者有很多异步任务,那么您可能需要创建自己的线程池或查看codeplex上的SmartThreadPool


希望这有帮助

在IIS中使用线程时要小心。IIS已经使用线程来处理单个请求,可用的线程总数是有限制的。@joel我可以为此创建新线程吗?这样我就不会弄乱IIS的限制了?这是操作系统的限制,而不是IIS的限制。这很有趣,但是很多事情都发生在应用程序代码的深处。我想我可以将所有日志对象添加到HttpContext项集合中,但是是否有一个全局等效的页面卸载可供我使用?如果我使用TaskParallelLibrary,而不是使用ThreadPool.QueueUserWorkItem和等效项,会怎么样,它保留作业的内部队列并设置线程数?线程始终来自同一个应用程序池-对于IIS托管的应用程序,它们来自IIS中的应用程序池;对于自托管或控制台/windows应用程序,它们来自您自己的应用程序池,默认情况下由.net为您创建。这是因为线程池与进程相关联。因此,任务并行库将使用与应用程序相同的线程池中的线程。谢谢,我得到了错误信息,认为任务有自己的线程池,仅限于几个线程。。。