惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
SegmentFault 最新的问题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Attack and Defense Labs
Attack and Defense Labs
F
Full Disclosure
Vercel News
Vercel News
N
News | PayPal Newsroom
The GitHub Blog
The GitHub Blog
H
Hacker News: Front Page
H
Heimdal Security Blog
P
Privacy International News Feed
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cisco Blogs
L
Lohrmann on Cybersecurity
D
Docker
Recent Announcements
Recent Announcements
Security Archives - TechRepublic
Security Archives - TechRepublic
人人都是产品经理
人人都是产品经理
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
T
Tailwind CSS Blog
C
Check Point Blog
博客园 - 叶小钗
Google Online Security Blog
Google Online Security Blog
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
S
Secure Thoughts
博客园 - Franky
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
P
Palo Alto Networks Blog
Latest news
Latest news
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
Last Week in AI
Last Week in AI
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
Hacker News: Ask HN
Hacker News: Ask HN
T
Threatpost
T
Tenable Blog
P
Privacy & Cybersecurity Law Blog
WordPress大学
WordPress大学

博客园 - 谢小漫

弹出选择窗体控件(附源码) 获取枚举描述信息(Description)2 - 谢小漫 - 博客园 mshtml组件引用的问题 导出所有用户表到excel Sql Server数据导出EXCEL C#的串口编程 DataReceived XML-RPC.NET的X509Certificates如何使用呢 XML-RPC.NET 在读《C#和.NET 2.0实战》 如何在winform中用委托做异步 C#的串口编程 重新开始学习.net 在看Test-Driven Development In Microsoft .NET 最近了解过的一个支付接口 网站的第三天 BAIDU的第一个搜索访问进入网站 不错的日期选择 星期六提交sitemap 关于代码自动生成器
如何在ASP.NET中做异步
谢小漫 · 2008-12-12 · via 博客园 - 谢小漫

先来两个都是延时两秒的方法,需要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秒,两个方法与页面在同一个线程里执行。

先定义委托:

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秒之间,也是两个方法在不同的线程执行,其中两个都不与页面线程相同。