ASP.NET 2.0中的异步页面 实例

 
ASP.NET 2.0中的异步页面 实例 (2007-10-14 09:35:17)
 

ASP.NET 2.0中的异步页面

 

ASP.NET页面运行原理

IIS ISAPI Extension

ASP.NET工作进程

IIS应用程序池(进程池)

– 隔离级别

     ASP.NET Web请求的处理过程

 

ASP.NET 页面运行原理

 ASP.NET 1.X中实现异步页面

– 实现IHttpAsyncHandler接口

– 自定义的线程池

– 缺点:

" 实现复杂

" 没有系统机制的支持

ASP.NET 2.0中的异步页面

– 设置

<%@ Page Async="true" ... %>

– 代码

AddOnPreRenderCompleteAsync (

new BeginEventHandler(MyBeginMethod),

new EndEventHandler (MyEndMethod)

);

 

异步调用Web服务

proxy.FooCompleted += new FooCompletedEventHandler(OnFooCompleted);

proxy.FooAsync (...);

...

void OnFooCompleted (Object source,FooCompletedEventArgs e)

{

// Called when Foo completes

}

【实例代码】

首先如果要在页面进行异步调用,一定要把页面的Async属性设置为true:

<%@ Page Language="C#" Async="true" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

首先我们看看页面中简单的异步调用实现获取目标网页的代码:

using System.Text.RegularExpressions; //正则表达式的引用空间

 

System.Net.WebRequest myRequest;

 

protected void Page_Load(object sender, EventArgs e)

{

Label1.Text = "Page_Load: thread #" + System.Threading.Thread.CurrentThread.GetHashCode();

    BeginEventHandler bh = new BeginEventHandler(this.BeginGetAsyncData);

    EndEventHandler eh = new EndEventHandler(this.EndGetAsyncData);

  

 AddOnPreRenderCompleteAsync(bh, eh);

    string address = "http://msdn.microsoft.com/";

    myRequest = System.Net.WebRequest.Create(address);

}

 

protected IAsyncResult BeginGetAsyncData(Object src, EventArgs args, AsyncCallback cb, Object state)

{

        Label2.Text = "BeginGetAsyncData: thread #" + System.Threading.Thread.CurrentThread.GetHashCode();

        return myRequest.BeginGetResponse(cb, state);

}

protected void EndGetAsyncData(IAsyncResult ar)

{

    Label3.Text = "EndGetAsyncData: thread #" + System.Threading.Thread.CurrentThread.GetHashCode();

    //System.Net.WebResponse myResponse = myRequest.EndGetResponse(ar);

    //result.Text = new StreamReader(myResponse.GetResponseStream()).ReadToEnd();

    //myResponse.Close();

    string str = "";

    using (System.Net.WebResponse response = myRequest.EndGetResponse(ar))

    {

        using (StreamReader reader = new StreamReader(response.GetResponseStream()))

        {

            str = reader.ReadToEnd();

        }

    }

    Regex reg = new Regex("href//s*=//s*/"([^/"]*)/"", RegexOptions.IgnoreCase);

    MatchCollection matchs = reg.Matches(str);

    StringBuilder sb = new StringBuilder(1024);

    foreach (Match match in matchs)

    {

        sb.Append(match.Groups[1]);

        sb.Append("<br/>");

    }

    result.Text = sb.ToString();

}

下面我们再看看通过注册到页的异步任务来实现同样的功能:

protected void Page_Load(object sender, EventArgs e)

{

     PageAsyncTask task = new PageAsyncTask(

             new BeginEventHandler(BeginGetAsyncData),

             new EndEventHandler(EndGetAsyncData),

             new EndEventHandler(TimeOutHandler),

             null);

    RegisterAsyncTask(task);

}

 

protected IAsyncResult BeginGetAsyncData(Object src, EventArgs args, AsyncCallback cb, Object state)

{

    string address = "http://msdn.microsoft.com/";

    myRequest = System.Net.WebRequest.Create(address);

 

    return myRequest.BeginGetResponse(cb, state);

}

 

protected void EndGetAsyncData(IAsyncResult ar)

{

    //等同于上面

}

 

protected void TimeOutHandler(IAsyncResult ar)

{

    Response.Write("超时!!!");

}

再看看一个服务器端与数据库进行异步回调的例子:

private SqlCommand cmd;

private SqlDataReader sdr;

 

protected void Page_Load(object sender, EventArgs e)

{

    this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);

 

    BeginEventHandler bh = new BeginEventHandler(this.BeginGetAsyncData);

    EndEventHandler eh = new EndEventHandler(this.EndGetAsyncData);

 

    AddOnPreRenderCompleteAsync(bh, eh);

}

 

protected IAsyncResult BeginGetAsyncData(Object src, EventArgs args, AsyncCallback cb, Object state)

{

    //服务器端异步访问数据库,注意一定要有 async=true;

    SqlConnection sc = new SqlConnection(";async=true;");

    sc.Open();

    cmd = new SqlCommand("select * from employee", sc);

    return cmd.BeginExecuteReader(cb, state);

}

 

protected void EndGetAsyncData(IAsyncResult ar)

{

    sdr = cmd.EndExecuteReader(ar);

}

 

protected void Page_PreRenderComplete(object sender, EventArgs e)

{

    this.GridView1.DataSource = sdr;

    this.GridView1.DataBind();

}

最后看看与WEB服务进行异步回调的例子

 

[MSDN注解]

1.      异步任务PageAsyncTask

ASP.NET 版本 2.0 允许您注册多个任务到页,并在呈现页之前异步运行这些任务。如果任务进程缓慢,且您不希望在执行它时拖延其他进程,则您可指定异步运行该任务。异步任务可并行或顺序执行。

PageAsyncTask 对象必须通过 RegisterAsyncTask 方法注册到页。页本身无需异步处理以执行异步任务。您可在页指令上将 Async 属性设置为 true(如下面的代码示例所示)或 false,异步任务将仍然异步处理:

<%@ Page Async="true" %>

当 Async 属性设置为 false 时,在所有异步任务完成之前,执行页的线程将被阻止。

任何在 PreRenderComplete 事件之前注册的异步任务如果还未执行,则将由页自动执行。在 PreRenderComplete 事件之后注册的异步任务必须通过 ExecuteRegisteredAsyncTasks 方法显式执行。ExecuteRegisteredAsyncTasks 方法也可用于在 PreRenderComplete 事件之前启动任务。ExecuteRegisteredAsyncTasks 方法执行页上所有未执行的注册异步任务。

默认情况下,如果异步任务未在 45 秒钟内完成,则它将超时。您可在 Web.config 文件或页指令中指定不同的超时值。Web.config 文件的 <pages> 节包含 asyncTimeout 属性,如下所示。

<system.web>

<pages asyncTimeout="30"> </pages>

</system.web>

页指令包含 AsyncTimeout 属性。

<%@ Page AsyncTimeout="30" %>

2.       AddOnPreRenderCompleteAsync

使用 AddOnPreRenderCompleteAsync 方法向异步网页添加处理程序。

可以注册多个异步处理程序;但一次只能运行一个处理程序。如果要同时处理多个异步方法,应使用单个 BeginEventHandler 方法,并从该处理程序启动多个异步操作。

异步处理程序是在 PreRender 和 PreRenderComplete 事件之间调用的。

首先,运行所有 Page 事件(通过 PreRender 事件),然后调用每个已注册的 BeginEventHandler 方法。当处理程序完成时,调用相应的 EndEventHandler 方法。如果存在多个异步处理程序,则调用下一个处理程序。

在调用了已注册的异步事件处理程序后,从 PreRenderComplete 事件开始调用其余的页事件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值