为什么 mvc4 asynccontroller不能异步执行
1个回答
展开全部
对于HTTP的请求响应模型,服务器无法主动通知或回调客户端,当客户端发起一个请求后,必须保持连接等待服务器的返回结果,才能继续处理,因此,对于客户端来说,请求与响应是无法异步进行,也就是说无论服务器如何处理请求,对于客户端来说没有任何差别。
那么ASP.NET异步指的又是什么,解决了什么问题呢?
在解释ASP.NET异步前,先来考察下ASP.NET线程模型。
ASP.NET线程模型
我们知道,一个WEB服务可以同时服务器多个用户,我们可以想象一下,WEB程序应该运行于多线程环境中,对于运行WEB程序的线程,我们可以称之为WEB线程,那么,先来看看WEB线程长什么样子吧。
我们可以用一个HttpHandler输出一些内容。
public class Handler : IHttpHandler{ public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; var thread = Thread.CurrentThread; context.Response.Write( string.Format("Name:{0}\r\nManagedThreadId:{1}\r\nIsBackground:{2}\r\nIsThreadPoolThread:{3}", thread.Name, thread.ManagedThreadId, thread.IsBackground, thread.IsThreadPoolThread) ); } public bool IsReusable { get {return true;} }} 你可以看到类似于这样的结果:
Name:
ManagedThreadId:57
IsBackground:True
IsThreadPoolThread:True
这里可以看到,WEB线程是一个没有名称的线程池中的线程,如果刷新这个页面,还有机会看到 ManagedThreadId 在不断变化,并且可能重复出现。说明WEB程序有机会运行于线程池中的不同线程。
为了模拟多用户并发访问的情况,我们需要对这个处理程序添加人为的延时,并输出线程相关信息与开始结束时间,再通过客户端程序同时发起多个请求,查看返回的内容,分析请求的处理情况。
public void ProcessRequest(HttpContext context){ DateTime begin = DateTime.Now; int t1, t2, t3; ThreadPool.GetAvailableThreads(out t1, out t3); ThreadPool.GetMaxThreads(out t2, out t3); Thread.Sleep(TimeSpan.FromSeconds(10)); DateTime end = DateTime.Now; context.Response.ContentType = "text/plain"; var thread = Thread.CurrentThread; context.Response.Write( string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, context.ApplicationInstance.GetHashCode(), begin, end, t2 - t1 ) );} 我们用一个命令行程序来发起请求,并显示结果。
static void Main(){ var url = new Uri("http://localhost:8012/Handler.ashx"); var num = 50; for (int i = 0; i < num; i++) { var request = WebRequest.Create(url); request.GetResponseAsync().ContinueWith(t => { var stream = t.Result.GetResponseStream(); using (TextReader tr = new StreamReader(stream)) { Console.WriteLine(tr.ReadToEnd()); } }); } Console.ReadLine();} 这里,我们同时发起了50个请求,然后观察响应的情况。
【注意】后面的结果会因为操作系统、IIS版本、管道模式、.NET版本、配置项 的不同而不同,以下结果为在Windows Server 2008 R2 + IIS7.5 + .NET 4.5 beta(.NET 4 runtime) + 默认配置 中测试的结果,在没有特别说明的情况下,均为重启IIS后第一次运行的情况。
这个程序在我的电脑运行结果是这样的:
那么ASP.NET异步指的又是什么,解决了什么问题呢?
在解释ASP.NET异步前,先来考察下ASP.NET线程模型。
ASP.NET线程模型
我们知道,一个WEB服务可以同时服务器多个用户,我们可以想象一下,WEB程序应该运行于多线程环境中,对于运行WEB程序的线程,我们可以称之为WEB线程,那么,先来看看WEB线程长什么样子吧。
我们可以用一个HttpHandler输出一些内容。
public class Handler : IHttpHandler{ public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; var thread = Thread.CurrentThread; context.Response.Write( string.Format("Name:{0}\r\nManagedThreadId:{1}\r\nIsBackground:{2}\r\nIsThreadPoolThread:{3}", thread.Name, thread.ManagedThreadId, thread.IsBackground, thread.IsThreadPoolThread) ); } public bool IsReusable { get {return true;} }} 你可以看到类似于这样的结果:
Name:
ManagedThreadId:57
IsBackground:True
IsThreadPoolThread:True
这里可以看到,WEB线程是一个没有名称的线程池中的线程,如果刷新这个页面,还有机会看到 ManagedThreadId 在不断变化,并且可能重复出现。说明WEB程序有机会运行于线程池中的不同线程。
为了模拟多用户并发访问的情况,我们需要对这个处理程序添加人为的延时,并输出线程相关信息与开始结束时间,再通过客户端程序同时发起多个请求,查看返回的内容,分析请求的处理情况。
public void ProcessRequest(HttpContext context){ DateTime begin = DateTime.Now; int t1, t2, t3; ThreadPool.GetAvailableThreads(out t1, out t3); ThreadPool.GetMaxThreads(out t2, out t3); Thread.Sleep(TimeSpan.FromSeconds(10)); DateTime end = DateTime.Now; context.Response.ContentType = "text/plain"; var thread = Thread.CurrentThread; context.Response.Write( string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, context.ApplicationInstance.GetHashCode(), begin, end, t2 - t1 ) );} 我们用一个命令行程序来发起请求,并显示结果。
static void Main(){ var url = new Uri("http://localhost:8012/Handler.ashx"); var num = 50; for (int i = 0; i < num; i++) { var request = WebRequest.Create(url); request.GetResponseAsync().ContinueWith(t => { var stream = t.Result.GetResponseStream(); using (TextReader tr = new StreamReader(stream)) { Console.WriteLine(tr.ReadToEnd()); } }); } Console.ReadLine();} 这里,我们同时发起了50个请求,然后观察响应的情况。
【注意】后面的结果会因为操作系统、IIS版本、管道模式、.NET版本、配置项 的不同而不同,以下结果为在Windows Server 2008 R2 + IIS7.5 + .NET 4.5 beta(.NET 4 runtime) + 默认配置 中测试的结果,在没有特别说明的情况下,均为重启IIS后第一次运行的情况。
这个程序在我的电脑运行结果是这样的:
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询