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

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy International News Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
V2EX - 技术
V2EX - 技术
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
G
GRAHAM CLULEY
L
Lohrmann on Cybersecurity
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
N
News and Events Feed by Topic
T
Tenable Blog
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
The Hacker News
The Hacker News
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
P
Proofpoint News Feed
Webroot Blog
Webroot Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
L
LangChain Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东

博客园 - 谢小漫

弹出选择窗体控件(附源码) 获取枚举描述信息(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秒之间,也是两个方法在不同的线程执行,其中两个都不与页面线程相同。