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

推荐订阅源

T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
P
Proofpoint News Feed
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
A
About on SuperTechFans
T
Tenable Blog
M
MIT News - Artificial intelligence
IT之家
IT之家
I
Intezer
D
DataBreaches.Net
爱范儿
爱范儿
T
Threatpost
C
CERT Recently Published Vulnerability Notes
云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
Spread Privacy
Spread Privacy
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AWS News Blog
AWS News Blog
博客园 - 聂微东
C
Check Point Blog
S
Securelist
有赞技术团队
有赞技术团队
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
D
Docker
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tailwind CSS Blog
L
Lohrmann on Cybersecurity
G
Google Developers Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LangChain Blog

博客园 - zguosir

[转载]转给自己的,跨业洗牌 [转载]挖一口属于自己的井 MSIL探索-IL介绍 MSIL探索-序 我的简历 我的技术特长 我的项目-物业收费 我的项目-人员定位 我的项目-证券分析 我的项目-工作票管理 我的项目-地衡读数 我的项目-物业管理(大厦版) 我的项目-财务系统 我的项目-图形拼接 我的项目-磁盘考试系统 - zguosir 我的项目-通用题库系统 收藏列表 DotNet中异步编程(APM)的研究2-三种聚集方式rendevousing DotNet中异步编程(APM)的研究1-异步编程介绍
DotNet中异步编程(APM)的研究3-代理与异步编程
zguosir · 2007-09-04 · via 博客园 - zguosir

DotNet中异步编程(APM)的研究3
代理与异步编程 (by zguosir/gshzheng)

除了调用FCL中提供的异步方法外,.Net提供了一个非常有用的机制,使得任何一个方法都可以异步的调用,换言之,任何一个方法,都可以在单独的一个线程中异步的执行,执行完毕后将结果返回到调用线程。

这个机制就是使用代理(delegate)。代理是C#中引入的相当聪明的语言元素。从现象上看,代理象C++中的类型安全函数指针,所以常用于事件定义或其它回掉机制。本质上,代理是个特殊的类,它封装了函数调用的功能。尤其是代理的异步调用功能,使程序开发的灵活性大大增加,也大量地屏蔽了多线程开发的难度。

对任何方法,定义一个与其签名相同的代理,就可以通过代理的BeginInvoke()EndInvoke()来异步的调用。下面是一个演示了异步调用阶乘计算的例子。

Example5

public class UseDelegate

{

     //要调用的方法

     public static int Factorial(int n)

     {

         if(n<=1) return 1;

         return n*Factorial(n-1);

     }

     public delegate int DelegateFactorial(int n);

     //异步调用

     public static void AsyncCall(int n)

     {

         DelegateFactorial dele=new DelegateFactorial(Factorial);

         dele.BeginInvoke(n,new AsyncCallback(cb_AsyncCall),null);

     }

     private static void cb_AsyncCall(IAsyncResult ar)

     {

         DelegateFactorial d=((ar as AsyncResult).AsyncDelegate) as DelegateFactorial;

         int i=d.EndInvoke(ar);

         Console.WriteLine(i);

     }

}

代理的BeginInvoke()的返回值是个AsyncResult对象,它实现了IAsyncResult接口,并且也记录了调用者代理实例dele,可以在回调函数中将ar强行转化为AsyncResult并取得AsyncDelegate后,通过它来调用EndInvoke()。注,其它的异步调用BeginOperation返回的对象不一定是AsyncResult类型,也未必有AsyncDelegate属性,需要借助于AsyncState参数等方式传入。

代理本质上是个类,继承自MulticastDelegateMulticastDelegate 是一个特殊类。编译器和其他工具可以从此类派生,但是开发人员不能显式地从此类进行派生。 当定义了一个代理,

public delegate int DelegateFactorial(int n);

编译器将会自动生成一个等价的类

public class DelegateFactorial : System.MulticastDelegate

{

     public DelegateFactorial(Object target, Int32 methodPtr);

     public  virtual void Invoke(Int32 n);

     public virtual IAsyncResult BeginInvoke(Int32 n,AsyncCallback callback, Object state);

     public virtual int EndInvoke(IAsyncResult result);

}

其中,构造方法在实例化一个代理对象时由CLR调用,并自动传入当前对象到第一个参数(如果是静态方法则传入null);Invoke()方法就是直接调用时的同步方法,目前的vs.net编译器不允许直接调用此方法;BeginInvoke()EndInvoke()方法就是一对异步方法,它们的方法签名的格式与代理定义相一致:

l           BeginInvoke()的后面固定为指定回调函数的两个参数;

l           代理定义的所有参数(包括ref,out参数),将作为BeginInvoke前面的参数;

l           EndInvoke()的最后一个参数,固定为IAsyncResult

l           如果代理的参数列表中有ref,out参数,将作为EndInvoke前面的参数;

l           EndInvoke()的返回值即为代理的返回值。