说到这就不得不谈.net的异步处理(Asynchronous),模型一般为BeginXXX,EndXXX,BeginXXX返回一个IAsycResult对象,其中包含对当前异步操作的信息,而EndXXX用户接受返回值,输出参数。.net从ThreadPool中分配一个空闲线程给BeginXXX然后立即返回给ThreadPool,等到异步处理结束时,.net又从ThreadPool中分配一个空闲线程用于处理EndXXX方法。这样就可能有足够的线程用于处理其它的事情。见于篇幅问题这里我们只谈asp.net 2.0的异步处理模型,我们都知道在1.x的时候要很好的建立页面的异步处理是比较麻烦的,可能微软很早就认识到了这一点,所以在2.0的版本中引入的新的页面处理模型,加入了方便的异步处理点(Asynchronous Point)在PreRender事件和PreRenderComplete事件之间,在这个异步点,页面需要等待所有的异步处理都完成,所以可以在页面呈现之前完成你需要的任何效果,极大简化了建立异步页面的方法。
首先你要在建立页面的@page声明中加入 Async="true",这是必须的。设置告诉asp.net要选用IHttpAsyncHandler来处理当前的页面。接下来你需要做的一般是在Page_Load事件处理中使用异步处理过程,现在有两种途径:
第一种就是使用Page.AddOnPreRenderCompleteAsync方法来处理需要异步处理的Begin和End方法集.如下:
AddOnPreRenderCompleteAsync(new BeginEventHandler(MyBeginMethod),new EndEventHandler(myEndMethod)); |
通过添加上面的方法后,页面执行通常的生命周期事件直到页面的PreRender事件触发.然后Asp.net调用先前在AddOnPreRenderCompleteAsync中的注册的Begin处理程序。通常在Begin处理程序中处理的是一些异步的web服务,IO以及SQL的处理,这样就可以极大的缓解.net线程池的压力。例如:
<%@ Page Async="true" Language="C#" %> <asp:Content ID="Content" ContentPlaceHolderID="Main" Runat="server"> <asp:Label ID="Output" Runat="server"></asp:Label> </asp:Content> public partial class AsyncPage : System.Web.UI.Page { private WebRequest m_Request; void Page_Load (object sender, EventArgs e) { AddOnPreRenderCompleteAsync ( new BeginEventHandler(BeginAsyncOperation), new EndEventHandler (EndAsyncOperation) ); } IAsyncResult BeginAsyncOperation (object sender, EventArgs e, AsyncCallback cb, object state) { m_Request = WebRequest.Create("http://www.dofor.cn"); return m_Request.BeginGetResponse (cb, state); } void EndAsyncOperation (IAsyncResult ar) { string text; using (WebResponse response = m_Request.EndGetResponse(ar)) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { text = reader.ReadToEnd(); } } Regex regex = new Regex ("hrefs*=s*"([^"]*)"", RegexOptions.IgnoreCase); MatchCollection matches = regex.Matches(text); StringBuilder builder = new StringBuilder(1024); foreach (Match match in matches) { builder.Append (match.Groups[1]); builder.Append("<br/>"); } Output.Text = builder.ToString (); } } |