AsyncController 如何避免使用 ASP.NET 工作线程?

Posted

技术标签:

【中文标题】AsyncController 如何避免使用 ASP.NET 工作线程?【英文标题】:How does AsyncController avoid using an ASP.NET worker thread? 【发布时间】:2011-10-18 12:18:53 【问题描述】:

AsyncController 究竟如何避免使用 ASP.NET 工作线程?如果我使用基于事件的模式(伪代码):

[AsyncTimeout(60000)]
public void WaitForWakeUp() 

    AsyncManager.OutstandingOperations.Increase();
    EventRaisedElsewhere += 
    state => 
    
        AsyncManager.OutstandingOperations.Decrease();
        return Content("Woke up because of " + state);
    ;

...然后根据Clay Lenharts 它不使用 ASP.NET 工作线程。这怎么可能?

我看了一点AsyncController 源代码,但什么都不懂,除了它使用了很多IAsyncResult 并且在某些地方使用了QueueUserWorkItem

但是BeginInvokeQueueUserWorkItem怎么能使用 ASP.NET 工作线程呢?肯定这两个都使用线程池线程,ASP.NET工作进程中肯定只有一个线程池吗?

根据 MSDN,

Web 服务器从线程池(worker 线程)并安排它处理传入的请求。这个工人 线程启动一个异步操作

工作线程返回线程池为另一个线程服务 网络请求。

当异步操作完成时,它会通知 ASP.NET。

但是对于任何重要的事情,听起来启动异步操作仍然需要一个线程来运行。只有在极其简单的情况下(例如使用 BCL 下载 Web 内容)才会完全展开和/或完全绑定 IOCP,对吗?

我之所以这么问,部分是因为我看到所有这些聊天服务器都是使用AsyncController 实现的,如果他们所做的只是“等待新消息”,我不明白如何在非线程池线程上完成。

【问题讨论】:

【参考方案1】:

你说得对。它确实使用 asp.net 线程来启动异步调用,但该线程完成并返回到池中。然后异步进程在工作线程池中的另一个线程上运行,然后通知 asp.net 它需要一个线程来处理结果。

效率更高,因为 asp.net 线程池限制传入连接,因此尽快释放这些连接可以让您更快地处理更多传入连接。

至少我是这么看的。

编辑 我不认为这是完全正确的。框架中定义的后台线程池只有一个,但您可以创建任意数量的其他线程,并创建自己的线程池,与后台线程池不同。

我相信这就是这里正在发生的事情。有少量工作线程处理请求。这些工作线程在后台池中生成线程来处理异步请求。

西蒙

【讨论】:

对不起,这太含糊了。 w3wp 工作进程只有一个 CLR 线程池,不是吗?那么上面的“工作线程池”指的是什么线程池?这是否与从中提取线程以服务传入的 http 请求的线程池相同的线程池?在那种情况下,为什么将操作方法​​调用程序线程返回到该线程池,然后立即拉出一个新线程,这会使任何事情变得更快?还有,如果线程返回到线程池,“等待”是怎么实现的?

以上是关于AsyncController 如何避免使用 ASP.NET 工作线程?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在 ASP.NET MVC 4 中使用 AsyncController 吗?

ASP.NET MVC2 AsyncController 可以访问 HttpContext.Current 吗?

在 R 中使用 as.numeric() 时如何避免数字舍入?

异步Action之AsyncController

如何避免 as.numeric() 中的“警告消息:强制引入的 NA”[重复]

如何在 MVC 3 中正确进行长轮询