• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

AsynchronousPagesinASP.NET2.0

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

看这里: http://msdn.microsoft.com/en-us/magazine/cc163725.aspx

ASP.NET2.0 异步页面技术是用来解决页面执行长时间,复杂逻辑代码所造成的页面长时间不呈现。它与我们平常说Ajax技术有着很大区别。

ASP.NET2.0异步技术采用.Net framework的多线程技术来解决的。当我们在ASP.NET页面中标记Async='True'时,页面编译器将会自动编译成异步类并实现IHttpasynchandler. 同时ASPNET_ISAPI会将请求带入异步管道进行实际的页面执行。

此时我们发现在Page_PreRender事件之后,PreRenderComplete事件之前,它启动了一个后台线程来执行相应的任务。为什么会选择在这个事件时候发生,并且后台线程怎么找到并返回结果的呢?那是因为有个叫做Async point “异步点”的东西来决定的。

public partial class MyPages : System.Web.UI.Page
{
    
private const string RSSFEED = "http://weblogs.asp.net/despos/rss.aspx";
    
private WebRequest weq;
    
protected void Page_Load(object sender, EventArgs e)
    {
        AddOnPreRenderCompleteAsync(
new BeginEventHandler(BeginResult),
            
new EndEventHandler(EndTask));
    }
    IAsyncResult BeginResult(Object src, EventArgs args, AsyncCallback cb, Object state)
    {
        Trace.Warn(
"custom message","Begin async:thread=" + Thread.CurrentThread.ManagedThreadId.ToString());
        weq 
= WebRequest.Create(RSSFEED);
        
return weq.BeginGetResponse(cb, state);
    }
    
void EndTask(IAsyncResult ar)
    {
        
string text;
        
using (WebResponse response = weq.EndGetResponse(ar))
        {
            StreamReader reader;
            
using (reader = new StreamReader(response.GetResponseStream()))
            {
                text 
= reader.ReadToEnd();
            }
            Literal1.Text 
= text;
        }
    }  
}

但是当我们要同时处理多个异步任务,我们怎么做呢?通常

 void Page_Load (object sender, EventArgs e)
    {
        AddOnPreRenderCompleteAsync (
            
new BeginEventHandler(BeginTask),
            
new EndEventHandler(EndTask));

        AddOnPreRenderCompleteAsync(
            
new BeginEventHandler(BeginTask1),
            
new EndEventHandler(EndTask1));
        
        AddOnPreRenderCompleteAsync(
            
new BeginEventHandler(BeginTask1),
            
new EndEventHandler(EndTask1));
    }

但是,当我们启动Trace 的时候我们会发现:

启动了2个线程,异步页面只有所有的请求返回。也就意味着如果我们写N个异步调用就启动N个异步线程,并且如果任何其中一个卡死,那页面就会block掉直到超时.

当然那样是不好的,其实面对这样的问题,我们都需要自定义IAsyncResult.在内部,我们可以控制是否所有的任务都完成才返回,具体实现请下载代码查看(CompositeAsyncResult.cs)

当我们再执行下列代码时,会发现始终只启动了一个线程。

 void Page_Load (object sender, EventArgs e)
    {
        AddOnPreRenderCompleteAsync (
            
new BeginEventHandler(BeginTask),
            
new EndEventHandler(EndTask));
    }
    IAsyncResult BeginTask(
object sender, EventArgs e, AsyncCallback cb, object state)
    { 
        
// Create the custom AsyncResult object
        CompositeAsyncResult ar = new CompositeAsyncResult(cb, state, 2);   
        
// Fire the first request
        req1 = WebRequest.Create(RSSFEED1);
        ar1 
= req1.BeginGetResponse(ar.Callback, state);
        
// Fire the second request
        req2 = WebRequest.Create(RSSFEED2);
        ar2 
= req2.BeginGetResponse(ar.Callback, state);
        
return ar;
    }

 

 同时,我要提一下PageAsyncTask方法:

看看MSDN上的解释,我们就会发现,它是独立Asynchronous 页面的。就算你将页面的Async=‘false’,它一样的实行异步任务,只是将会阻塞页面线程。

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

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

<%@ Page Async="true" %>

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

任何在 ExecuteRegisteredAsyncTasks 方法显式执行。ExecuteRegisteredAsyncTasks 方法也可用于在 PreRenderComplete 事件之前启动任务。ExecuteRegisteredAsyncTasks 方法执行页上所有未执行的注册异步任务。

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

<system.web>

<pages asyncTimeout="30">

</pages>

</system.web>

页指令包含 AsyncTimeout 属性。

<%@ Page AsyncTimeout="30" %>

同样的功能,更简洁的代码:

public partial class RssAsync : System.Web.UI.Page
{
    
private const string RSSFEED1 = "http://weblogs.asp.net/despos/rss.aspx";
    
private const string RSSFEED2 = "http://blogs.ugidotnet.org/dinoes/rss.aspx";
    RssFeedAsyncReader rss1, rss2;
    
public string rssData;

    
void Page_Load (object sender, EventArgs e)
    {
        
this.PreRenderComplete += new EventHandler(RssAsync_PreRenderComplete);

        rss1 
= new RssFeedAsyncReader(RSSFEED1);
        rss2 
= new RssFeedAsyncReader(RSSFEED2);

        PageAsyncTask task1 
= new PageAsyncTask(
            
new BeginEventHandler(rss1.BeginRead),
            
new EndEventHandler(rss1.EndRead),
            
null,
            
null,
            
true);
        PageAsyncTask task2 
= new PageAsyncTask(
            
new BeginEventHandler(rss2.BeginRead),
            
new EndEventHandler(rss2.EndRead),
            
null,
            
null,
            
true);

        RegisterAsyncTask(task1);
        RegisterAsyncTask(task2);
    }

    
void RssAsync_PreRenderComplete(object sender, EventArgs e)
    {
        rssData 
= rss1.GetRssData() + rss2.GetRssData();
    }
    
}

DownLoad

了解更多关于PageAsyncTask,点击:http://msdn.microsoft.com/zh-cn/library/system.web.ui.pageasynctask(VS.80).aspx

到了这里,我们会有些疑问,到底用哪个方法(AddOnPreRenderCompleteAsync还是RegisterAsyncTask)适合呢?他们有什么区别呢?

相同点: 从功能上讲,他们是相同的,页面请求的执行都分为2个阶段,在异步点(Async point)之前和之后.

不同点:

1. RegisterAsyncTask 是被设计用来运行页面类的异步任务的API。不仅仅是异步页面。AddOnPreRenderCompleteAsync 是专门用来执行异步页面的API。

2. One is that RegisterAsyncTask executes the End handler on a thread with a richer context than AddOnPreRenderCcompleteAsync. The thread context includes impersonation and Httpcontext information that is missing in the thread serving the End handler of a classic asynchronous page. In addition, RegisterAsyncAsyncTask allow you to set a timeout to ensure that any task doesn't run for more than a given number of seconds.

The other difference is that RegisterAsyncTask makes the implementation of multiple calls to remote sources significantly easier. You can have parallel execution by simply setting a Boolean flag, and you don't need to create and manage your own IAsyncResult object.

The bottom line is that you can use either approach for a single task, but you should opt for RegisterAsyncTask when you have multiple task to execute simultancely.


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
ASP.NET下使用jQuery UI下的Dialog,服务器端按钮无响应的问题。发布时间:2022-07-10
下一篇:
Asp.net下from认证统一认证配置发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap