根据以上的数据,我们可以得出结论,要提高系统响应时间与并发处理数,应尽可能减少WEB线程的等待。
【略】请各位自行查验当一次并发全部处理完毕后再次测试的处理情况。
【略】请各位自行查验当处理程序中使用线程池处理等待任务的处理情况。
如何减少WEB线程的等待呢,那就应该尽早的结果ProcessRequest方法,前一篇中讲到,对于一些需要等待完成的任务,可以使用异步方法来做,于是我们可以在ProcessRequest中调用异步方法,但问题是当ProcessRequest结束后,请求处理也即将结束,一但请求结束,将没有办法在这一次请求中返回结果给客户端,但是此时,异步任务还没有完成,当异步任务完成时,也许再也没有办法将结果传给客户端了。(难道用轮询?囧)
我们需要的方案是,处理请求时可以暂停处理(不是暂停线程),并保持客户端连接,在需要时,向客户端输出结果,并结束请求。
498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/6E15529419.png" />
在这个模型中,可以看到,对于WebServerRuntime来说,我们的请求处理程序就是一个异步方法,而对于客户端来说,却并不知道后面的处理情况。无论在WebServerRuntime或是我们的处理程序,都没有直接占用线程,一切由何时SetComplete决定。同时可以看到,这种模式需要WebServerRuntime的紧密配合,提供调用异步方法的接口。在ASP.NET中,这个接口就是IHttpAsyncHandler。
异步ASP.NET处理程序
首先,我们来实现第一个异步处理程序,在适当的时候触发结束,在开始和结束时输出一些信息。
- public class Handler : IHttpHandler, IHttpAsyncHandler
- {
- public void ProcessRequest(HttpContext context)
- {
- //异步处理器不执行该方法
- }
- public bool IsReusable
- {
- //设置允许重用对象
- get { return false; }
- }
- //请求开始时由ASP.NET调用此方法
- public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
- {
- context.Response.ContentType = "text/xml";
- context.Response.Write("App:");
- context.Response.Write(context.ApplicationInstance.GetHashCode());
- context.Response.Write("\tBegin:");
- context.Response.Write(DateTime.Now.ToString("mm:ss,ffff"));
- //输出当前线程
- context.Response.Write("\tThreadId:");
- context.Response.Write(Thread.CurrentThread.ManagedThreadId);
- //构建异步结果并返回
- var result = new WebAsyncResult(cb, context);
- //用一个定时器来模拟异步触发完成
- Timer timer = null;
- timer = new Timer(o =>
- {
- result.SetComplete();
- timer.Dispose();
- }, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
- return result;
- }
- //异步结束时,由ASP.NET调用此方法
- public void EndProcessRequest(IAsyncResult result)
- {
- WebAsyncResult webresult = (WebAsyncResult)result;
- webresult.Context.Response.Write("\tEnd:");
- webresult.Context.Response.Write(DateTime.Now.ToString("mm:ss,ffff"));
- //输出当前线程
- webresult.Context.Response.Write("\tThreadId:");
- webresult.Context.Response.Write(Thread.CurrentThread.ManagedThreadId);
- }
- //WEB异步方法结果
- class WebAsyncResult : IAsyncResult
- {
- private AsyncCallback _callback;
- public WebAsyncResult(AsyncCallback cb, HttpContext context)
- {
- Context = context;
- _callback = cb;
- }
- //当异步完成时调用该方法
- public void SetComplete()
- {
- IsCompleted = true;
- if (_callback != null)
- {
- _callback(this);
- }
- }
- public HttpContext Context
- {
- get;
- private set;
- }
- public object AsyncState
- {
- get { return null; }
- }
- //由于ASP.NET不会等待WEB异步方法,所以不使用此对象
- public WaitHandle AsyncWaitHandle
- {
- get { throw new NotImplementedException(); }
- }
- public bool CompletedSynchronously
- {
- get { return false; }
- }
- public bool IsCompleted
- {
- get;
- private set;
- }
- }
- }
在