如何从CLR线程池而不是ASP.NET池创建ASP.NET页面中的线程?

时间:2010-10-24 10:28:19

标签: c# asp.net multithreading clr threadpool

如果我在ASP.NET页面上创建新线程,则IsThreadPoolThread属性为true。 第一个问题是,它来自ASP.NET池还是CLR池? 第二个问题是,如果是来自ASP.NET池那么如何从CLR创建一个线程而不使用ASP.NET池? 我需要一个长期运行请求的同步解决方案(full story)。

3 个答案:

答案 0 :(得分:8)

首先,ASP.NET线程池和CLR线程池之间没有区别。 ASP.NET处理CLR线程池上的页面,因此您的ASP.NET页面将始终具有IsThreadPoolThread == true。

我很好奇你是如何创建你的线程的。您使用的是System.Threading.Thread构造函数,还是使用ThreadPool.QueueUserWorkItem?如果您使用的是ThreadPool.QueueUserWorkItem,那么您获得的线程来自常规的.net线程池。

最后,正如我posted before一样,从ASP.NET中尝试长时间运行任务总是一个坏主意。我的一般建议是使用后台Windows服务来处理这些请求,因为ASP.NET可以随时终止后台线程。此处有更多详细信息,如果您必须在IIS中执行此操作:http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx

答案 1 :(得分:4)

虽然有必要尽量减少对事务的影响并满足分布式事务中无法预见的需求,但在此示例中,仅仅因为进程长时间运行而无需重新发明IIS。整个“IIS可以随时死亡”的模因是恕我直言,大大夸大了。

是的,您可以手动重新启动IIS或应用程序池,但也可以重新启动执行相同作业的任何其他服务以获得相同的效果。对于自动回收,IIS使用重叠的工作进程,并且永远不会强制终止已启动的线程(除非发生超时)。如果是这种情况,我们会遇到任何托管应用程序的严重问题(什么是阻止IIS在启动后0.001ms杀死快速响应线程)

本质上,让IIS执行IIS最擅长的操作并且不要坚持同步操作,你只是浪费池的线程等待阻塞I / O,这是我认为你试图避免的。您已经通过转到异步处理程序(ASHX)做了一个很好的选择,使用IHttpAsyncHandler实现来生成您的自定义线程,这将阻止您的心愿,而不会影响Web应用程序及其池。一旦启动异步操作线程,asp.net线程将返回其自己的池,并准备开始提供新请求。如果池中默认限制为100个线程,并且假设您的进程处于低带宽状态,那么在管道空间耗尽之前,我绝对不会用完池线程:)有关如何构建异步处理程序的更多信息,请检查此链接(它是一篇旧文章,但不是有效的):

Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code

答案 2 :(得分:2)

ASP .NET中的线程实际上存在差异:工作线程和IO线程(我相信你称之为CLR线程的系统线程)。

现在ASP .NET在每个请求上都使用一个工作线程,除非使用自定义配置,并且这些工作线程的CPU数量有限;可以在IIS中设置此配置。 例如,当您使用委托在ASP.NET中启动异步任务时,您正在使用另一个工作线程。委托是在.NET中启动异步的快速而又脏的方法:)

如果你想启动一个不会耗尽工作线程的新线程,那么你必须显式启动一个新线程,如:new Thread()....等。现在这带来了很多代码管理,并没有遵循基于事件的异步模式。 但是,有一种方法可以安全地启动异步线程,即在对象上使用.NET自己的异步方法。你通常会使用asynch来处理类似SQL命令,webservice调用等等。所有这些都有一个BEGIN和一个END方法。 通过使用这些方法,您将永远不会使用工作线程,而是使用IO线程。

在异步页面方面,ASP .NET有一些技巧。 有两种选择:

  1. 异步页面:它使您的页面循环不同步。这基本上意味着请求异步页面。
  2. 异步页面任务:它允许您定义在页面启动时将触发异步的任务。它有点像Asynch线程,只是ASP .NET为你做了很多事情,而且它更受限制。
  3. 我没有所有细节,但请查看MSDN Library上的两个选项。 这是一篇关于这个主题的文章:asynch programmin