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

问题描述 投票:0回答:3

如果我在 ASP.NET 页面上创建一个新线程,则

IsThreadPoolThread
属性为 true。 第一个问题是,它是来自 ASP.NET 池还是 CLR 池? 第二个问题是,如果它来自 ASP.NET 池,那么如何从 CLR 创建线程而不使用 ASP.NET 池? 我需要一个针对长时间运行的请求的同步解决方案(完整故事)。

c# asp.net multithreading clr threadpool
3个回答
8
投票

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

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

最后,正如我之前发布过的那样,尝试从 ASP.NET 中长时间运行任务始终是一个坏主意。我的一般建议是使用后台 Windows 服务来处理这些请求,因为 ASP.NET 可能随时终止您的后台线程。如果您必须在 IIS 中执行此操作,请参阅更多详细信息


4
投票

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

本质上,让 IIS 做 IIS 最擅长的事情,而不是坚持同步操作,你只会浪费池的线程等待阻塞 I/O,这是我相信你试图避免的。您已经通过异步处理程序 (ASHX) 做出了不错的选择,使用

IHttpAsyncHandler

实现来生成您的自定义线程,该线程将在不影响 Web 应用程序及其池的情况下阻止您的愿望。一旦启动异步操作线程,asp.net 线程将返回到其自己的池并准备好开始服务新请求。池中默认限制为 100 个线程,并且考虑到您的进程是低 CPU 高带宽的,我怀疑在耗尽管道空间之前您不会用完池线程:)。有关如何构建异步处理程序的更多信息,请查看此链接(这是一篇旧文章,但仍然有效):


在服务器端 Web 代码中使用线程并构建异步处理程序


2
投票

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

如果您想启动一个不耗尽工作线程的新线程,那么您必须显式启动一个新线程,例如:new Thread()....等。现在它带有大量代码管理,并且不遵循基于事件的异步模式。 然而,有一种方法可以安全地启动异步线程,那就是在对象上使用 .NET 自己的异步方法。您通常会使用异步执行 SQL 命令、Web 服务调用等操作。所有这些都有 BEGIN 和 END 方法。 通过使用这些方法,您将永远不会使用工作线程,而是使用 IO 线程。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.