您的位置:首页 > 编程语言 > ASP

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

2008-10-31 15:32 274 查看
ASP.NET 2.0中的异步页面 实例 (2007-10-14 09:35:17)

var $tag='IT/科技';
var $tag_code='93b82ecd644c34fb116c4953b458c3bb';

分类:asp.net
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 事件开始调用其余的页事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: