ASP.NET框架中的异步页面 – 其他线程在哪里,如何重新连接?

前端之家收集整理的这篇文章主要介绍了ASP.NET框架中的异步页面 – 其他线程在哪里,如何重新连接?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
对于异步操作这个愚蠢的问题抱歉.这是我的理解.

IIS有一组有限的工作线程等待请求.如果一个请求是长时间运行的操作,它将阻止该线程.这导致更少的线程来服务请求.

解决方法 – 使用异步页面.当一个请求进来时,主工作线程被释放,另一个线程在其他地方被创建.因此,主线程可以提供其他请求.当该请求在该另一线程上完成时,从主线程池中挑选另一个线程,并将响应发送回客户端.

1)这些其他线程位于哪里?是否有另一个线程池?

2)如果ASP.NET喜欢在这个其他线程池(?)中创建新的线程,为什么不增加主工作池中的线程数量 – 它们都运行在同一台机器上?我没有看到将该请求移动到这个其他线程池的优点.内存/ cpu应该是一样的吗?

3)如果主线程向另一线程发出请求,为什么请求不会断开连接?它将请求手动移交给别的其他工作线程,当长时间运行的进程完成时,它从主工作池中选择一个线程,并向客户端发送响应.我很惊讶,但是如何工作?

解决方法

您没有说出使用哪个版本的IIS或ASP.NET.很多人谈论IIS和ASP.NET,就像它们是一样的,但是他们真的是两个组件在一起工作.请注意,IIS 6和7监听一个I / O完成端口,它们从HTTP.sys中获取完成数据. IIS线程池用于此,并且其最大线程计数为256.该线程池的设计方式不能很好地处理长时间运行的任务. IIS团队的建议是切换到另一个线程,如果要进行大量工作,例如由IIS 7上的ASP.NET ISAPI和/或ASP.NET“集成模式”处理程序完成.否则,您将绑定IIS阻止IIS线程阻止IIS从HTTP.sys中获取完成机会您可能不关心任何问题,因为您不是在编写本机代码,也就是说,您不是为了编写ISAPI或本机处理程序IIS 7管道.你可能只是使用ASP.NET,在这种情况下,你对它的线程池和它的工作方式更感兴趣.

http://blogs.msdn.com/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx上有一篇博文,解释了ASP.NET如何使用线程.请注意,对于IIS 7上的ASP.NET v2.0和v3.5,您应该将MaxConcurrentRequestsPercpu增加到5000 – 这是在这些平台上默认设置为12的错误. IIS 7中ASP.NET v4.0中MaxConcurrentRequestsPercpu的新默认值为5000.

回答你的三个问题:

1)首先,一点点引.每个cpu只能执行1个线程.当你有更多的时候,你会付出代价 – 每次cpu切换到另一个线程时都需要一个上下文切换,这些都是昂贵的.然而,如果一个线程被阻塞等待工作,那么切换到另一个可以执行的线程是有意义的.

所以如果我有一个线程正在做大量的计算工作,并大量使用cpu,这需要很长时间,我应该切换到另一个线程?没有!当前线程正在有效地使用cpu,因此切换只会导致上下文切换的成本.

所以如果我有一个线程,使HTTP或SOAP请求到另一台服务器需要很长时间,我应该切换线程?是!您可以异步执行HTTP或SOAP请求,因此一旦发送“发送”,您可以放松当前线程,而不是使用任何线程,直到“接收”完成I / O.在“发送”和“接收”之间,远程服务器正忙,因此本地您不需要在线程上阻塞,而是使用.NET Framework中提供的异步API,以便您可以放松和完成后通知.

好的,所以你第一个问题是“这些其他线程位于哪里?还有另一个线程池?这取决于在.NET Framework中运行的大多数代码使用CLR ThreadPool,它由两种类型的线程,工作线程和i / o完成线程组成.如何不使用CLR ThreadPool的代码?那么它可以创建自己的线程,使用自己的线程池,或任何它想要的,因为它可以访问由操作系统提供的Win32 API.基于我们之前讨论的内容,线程来自哪里,线程是一个线程,就操作系统和硬件而言是无关紧要的.

2)在你的第二个问题中,你说:“我没有看到将这个请求移动到这个其他线程池的优点.你是正确的,认为切换没有任何优势,除非你要弥补刚刚执行的昂贵的上下文切换才能切换.这就是为什么我给出了一个缓慢的HTTP或SOAP请求到远程服务器的例子,这是一个很好的切换原因的例子.顺便说一句,ASP.NET不会创建任何线程.它使用CLR ThreadPool,该池中的线程完全由CLR管理.他们在确定何时需要更多线程方面做得很好.例如,这就是为什么ASP.NET可以轻松地从同时执行1个请求到同时执行300个请求而不做任何事情.传入的请求通过调用QueueUserWorkItem发布到CLR ThreadPool,CLR决定何时调用WaitCallback(请参阅MSDN).

3)第三个问题是,“如果主线程向另一个线程发出请求,为什么请求不会断开连接?那么当请求最初到达服务器时,IIS从HTTP.sys中取出I / O完成. IIS然后调用ASP.NET的处理程序(或ISAPI). ASP.NET立即将请求排队到CLR Threadpool,并将待处理状态返回给IIS.这个挂起的状态告诉IIS我们还没有完成,但是一旦完成,我们就会通知你.现在ASP.NET管理该请求的生命周期.当CLR ThreadPool线程调用ASP.NET WaitCallback(参见MSDN)时,它可以在该线程上执行整个请求,这是正常情况.或者如果请求是我们称为异步的,那么它可以切换到一个或多个其他线程 – 即.它有一个异步模块或处理程序.无论哪种方式,请求完成都有很好的定义方式,而最终这样做的时候,ASP.NET会告诉我们IIS,IIS会将最终的字节发送给客户端,如果Keep-Alive是不被使用

问候,托马斯

猜你在找的asp.Net相关文章