谢小漫

挖掘数据的地瓜 联系:catcn@qq.com

如何在ASP.NET中做异步

先来两个都是延时两秒的方法,需要using System.Threading;using System.Collections.Generic;

private void GetData()
{
    Label1.Text 
+= "<br>Now: thread1 @ #" + Thread.CurrentThread.GetHashCode();
    Thread.Sleep(
2000);//延时2秒
}
private void GetData2()
{
    Label1.Text 
+= "<br>Now: thread2 @ #" + Thread.CurrentThread.GetHashCode();
    Thread.Sleep(
2000);//延时2秒
}
第一个为页面顺序执行的按钮:
protected void Button1_Click(object sender, EventArgs e)
{
    
//直接运行两个延时方法,页面运行大于4秒
    GetData(); GetData2();
}
打开trace后可以看到,页面的执行时间大于4秒,两个方法与页面在同一个线程里执行。
 
第二个为参考上一篇文章如何在winform中用委托做异步的,也把委托做异步用在ASP.NET上:
先定义委托:
private delegate void VoidDelegate();
添加委托异步的按钮,需要注意,必须添加EnInvoke()等待异步方法完成。
protected void Button2_Click(object sender, EventArgs e)
{
    
//使用委托异步运行两个方法
    VoidDelegate vd = GetData;
    vd 
+= GetData2;
    List
<IAsyncResult> il = new List<IAsyncResult>();
    
foreach (VoidDelegate v in vd.GetInvocationList())
    {
        il.Add(v.BeginInvoke(
nullnull));
    }
    
int ii = 0;
    
foreach (VoidDelegate v in vd.GetInvocationList())
    {
        v.EndInvoke(il[ii]);
//等待方法结束
        ii = ii + 1;
    }
}
运行后可以看到:页面两个方法都运行了,执行时间是2.0-3秒之间,两个方法在不同的线程执行,其中一个可能与页面线程相同(通常是第一次创建新的线程时候为不同,时间上也会接近三秒的。2.0秒左右的时间因为线程是在线程池里边拿出来用,不用创建新线程。)。
 
第三个是使用AddOnPreRenderCompleteAsync向Page注册两个异步方法,不过,页面回调会出错。具体原因没有找到?AddOnPreRenderCompleteAsync只能注册一个异步事件?
网上大部分的ASP.NET异步代码都是这个的,也只是注册一个异步方法,虽然是给出了实例,但是对比不是很明显:
 protected void Button3_Click(object sender, EventArgs e)
 {
     
//使用AddOnPreRenderCompleteAsync向Page注册两个异步方法,二次页面回调会出错(?不知道原因)
     
//另外页面的async也需要设置为true
     BeginEventHandler bh = new BeginEventHandler(GetDataAsync);
     bh 
+= new BeginEventHandler(GetData2Async);

     EndEventHandler eh 
= new EndEventHandler(EndGetAsyncData);
     eh 
+= new EndEventHandler(EndGet2AsyncData);
     Page.AddOnPreRenderCompleteAsync(bh, eh);
 }
 IAsyncResult GetDataAsync(Object src, EventArgs args, AsyncCallback cb, Object state)
 {
     VoidDelegate vd 
= GetData;
     
return vd.BeginInvoke(cb, state);
 }
 IAsyncResult GetData2Async(Object src, EventArgs args, AsyncCallback cb, Object state)
 {
     VoidDelegate vd 
= GetData2;
     
return vd.BeginInvoke(cb, state);
 }
 
void EndGetAsyncData(IAsyncResult ar) { }
 
void EndGet2AsyncData(IAsyncResult ar) { }
注意,如注释所示:页面的async也需要设置为true。
运行时间上和委托的一样:在2.0到3秒之间,也是两个方法在不同的线程执行,其中一个可能与页面线程相同。
 
第四个是使用RegisterAsyncTask来做异步。应该说上边的AddOnPreRenderCompleteAsync注册一个事件还可以,两个事件就用应该用RegisterAsyncTask或者委托来做异步。

protected void Button4_Click(object sender, EventArgs e)
{
    PageAsyncTask asyncTask1 
= new PageAsyncTask(
        
new BeginEventHandler(GetDataAsync),
        
new EndEventHandler(EndGetAsyncData),
        
new EndEventHandler(TimeoutAsyncData),
        
nulltrue);//关键:最后一个为true:指示任务能否与其他任务并行处理的值

    PageAsyncTask asyncTask2 
= new PageAsyncTask(
        
new BeginEventHandler(GetData2Async),
        
new EndEventHandler(EndGet2AsyncData),
        
new EndEventHandler(Timeout2AsyncData),
        
nulltrue);

    Page.RegisterAsyncTask(asyncTask1);
    Page.RegisterAsyncTask(asyncTask2);

    Page.ExecuteRegisteredAsyncTasks();
}
void TimeoutAsyncData(IAsyncResult ar) { }
void Timeout2AsyncData(IAsyncResult ar) { }

运行时间也是在2.0到3秒之间,也是两个方法在不同的线程执行,其中两个都不与页面线程相同。
待会回来打包事例。就一个页面的代码:https://files.cnblogs.com/catcn/MyDelayWeb.rar

posted on 2008-12-12 19:08  谢小漫  阅读(821)  评论(0编辑  收藏  举报

导航

. .