什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2

时间:2022-08-27 18:46:45

现在扩充下上篇文章的类(AsyncTest),提供更多的例子并从中做下简单的对比从新的认识下异步的内部机制,下面我们增加一个新的委托

1,我们添加一个新方法(计算年薪YearlySalary)

public decimal YearlySalary(decimal salary, int monthCount, decimal bonus);

2,为这个方法增加异步的功能,这样我们仍然使用委托(Delegate)

public delegate decimal SalaryEventHandler(decimal salary, int monthCount, decimal bonus);

 

经过简单修改后,下面是我们新的AsyncTest

Code1

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2// 我们使用委托来提供.Net的异步机制
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 public   delegate   string  AsyncEventHandler( string  name);  //  对应Hello 方法
 3 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 public   delegate   decimal  SalaryEventHandler( decimal  salary,  int  monthCount,  decimal  bonus);  //  对应YearlySalary方法
 4 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 public   class  AsyncTest
 5 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    public string Hello(string name)
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return "Hello:" + name;
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// <summary>
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// 计算一年的薪水
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// </summary>
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// <param name="salary">月薪</param>
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// <param name="monthCount">一年支付月数量</param>
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// <param name="bonus">奖金</param>
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    /// <returns></returns>

18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    public decimal YearlySalary(decimal salary, int monthCount, decimal bonus)
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //添加辅助方法,查看当前的线程ID
21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine("Thread ID:#{0}", Thread.CurrentThread.ManagedThreadId);
22什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
23什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return salary * monthCount + bonus;
24什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

25什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

 

这里用.NET Reflector 5 来反编译,之所以用这个,因为比微软的会更加清晰明了.如果想了解这个工具的朋友可查看(http://reflector.red-gate.com/)

什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2

1

开始我先对图1中的小图标进行个简单的解释

什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 = (Class)   什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 = 类继承的基类 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 = sealed(委托)

什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 = 类的构造函数 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 = 方法 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 = virtual方法

 

下面我们先比较下SalaryEventHandler AsyncEventHandler 委托的异同.

1)      SalaryEventHandler

public delegate decimal SalaryEventHandler(decimal salary, int monthCount, decimal bonus);

什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2

2.1

编译器生成的类Code2.1(2.1) 
Code 2.1

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2     public   sealed   class  SalaryEventHandler : MulticastDelegate
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2     {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public SalaryEventHandler(object @object, IntPtr method)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2.}
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public virtual IAsyncResult BeginInvoke(decimal salary, int monthCount, decimal bonus,
 AsyncCallback callback, 
object @object)
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public virtual decimal EndInvoke(IAsyncResult result)
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public virtual decimal Invoke(decimal salary, int monthCount, decimal bonus)
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

2)      AsyncEventHandler

public delegate string AsyncEventHandler(string name);

什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2

2.2

编译器生成的类Code2.2(2.2)

Code2.2

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2     public   sealed   class  AsyncEventHandler : MulticastDelegate
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2     {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public AsyncEventHandler(object @object, IntPtr method)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2.}
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object)
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public virtual string EndInvoke(IAsyncResult result)
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        public virtual string Invoke(string name)
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

 

对比两个委托(事实上是一个sealed 的类),都继承于System.MuliticaseDelegate, 三个virtual Invoke / BeginInvoke / EndInvoke 方法.

//同步方法

Invoke : 参数的个数,类型返回值都不相同

 

 

//异步方法,作为一组来说明

BeginInvoke : 参数的个数和类型不同,返回值相同

EndInvoke : 参数相同,返回值不同

 

这里我们先介绍下 Invoke这个方法, 我们用SalaryEventHandler委托为例(直接调用Code 1 的类)

Code 3

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2class  Program
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void Main(string[] args)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //添加辅助方法,查看当前的线程ID
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine("Main Thread ID:#{0}", Thread.CurrentThread.ManagedThreadId);
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest test = new AsyncTest();
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //[1],我们习惯的调用方式
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal v1 = test.YearlySalary(10000015100000);
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //使用委托调用
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler salaryDelegate = test.YearlySalary;
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //[2],编译器会自动的把[2]转变成[3]Invoke的调用方式,[2]和[3]是完全相同的
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal v2 = salaryDelegate(10000015100000);
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //[3]
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal v3 = salaryDelegate.Invoke(10000015100000);
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine("V1:{0},V2:{1},V3:{2}", v1, v2, v3);
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.ReadLine(); // 让黑屏等待,不会直接关闭..
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

输出的结果

什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2

3

从结果可以看出,他们是同一个线程调用的(都是#10).这就说明[1],[2],[3]是同步调用

[2],[3]对比[1], 只不过[2],[3]是通过委托的方式(其实我们可以说成“通过代理的方式完成”),[1]是直接的调用.举一个我们平常生活中例子:买机票,我们到代理点购买机票而不是直接跑到机场购买,就好像我们叫别人帮我们买机票一样,最后到手的机票是一样的, SalaryEventHandler就是我们的代理点.所以用代理的方式还是直接调用的方式,他们提供的参数和返回值必须是一样的.

 

接下来我们开始讲异步机制核心的两个方法BeginInvoke/EndInvoke,他们作为一个整体来完成Invoke方法的调用,不同于Inoke方法的是他们是异步执行(另外开一个线程执行),下面先解释下他们的作用

BeginInvoke 开始一个异步的请求,调用线程池中一个线程来执行
EndInvoke : 完成异步的调用处理返回值  异常错误.

注意: BeginInvokeEndInvoke必须成对调用.即使不需要返回值,但EndInvoke还是必须调用,否则可能会造成内存泄漏.


我们来对比下 SalaryEventHandler AsyncEventHandler委托反编译BeginInoke后的异同.

SalaryEventHandler 委托:

public virtual IAsyncResult BeginInvoke(decimal salary, int monthCount, decimal bonus, AsyncCallback callback, object @object)

AsyncEventHandler 委托:

public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object)

 

可以看出参数的个数和类型是不同的,我们把焦点放到他们的相同点上,

1,返回值是相同的返回IAsyncResult 对象(异步的核心). IAsyncResult是什么呢简单的说,存储异步操作的状态信息的一个接口,也可以用他来结束当前异步.具体的可以看下 http://msdn.microsoft.com/zh-cn/library/system.iasyncresult(VS.80).aspx

 

2,编译器会根据委托的参数个数和类型生成相应的BeginInvoke方法,只有最后两个参数是永远相同的,他提供一个AsyncCallback 委托(public delegate void AsyncCallback(IAsyncResult ar);和一个 Object 对象.

 

我们再来看看EndInvoke的异同.

SalaryEventHandler 委托:

public virtual decimal EndInvoke(IAsyncResult result)

AsyncEventHandler 委托:

public virtual string EndInvoke(IAsyncResult result)

 

EndInvoke的参数是一样的唯一是在是返回值不同(他们会根据自己委托的返回值类型生成自己的类型)

 

,下面我会通过例子来说明BeginInvoke/EndInvoke,还是使用SalaryEventHandler委托为例(直接调用Code 1 的类)

 

.Net Framework 提供了两种方式来使用异步方法

第一种通过IAsyncResult 对象

Code 4.1

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2class  Program
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static IAsyncResult asyncResult;
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void Main(string[] args)
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest test = new AsyncTest();
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler dele = test.YearlySalary;
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //异步方法开始执行,返回IAsyncResult(存储异常操作的状态信息) 接口,同时EndInvoke 方法也需要他来作为参数来结束异步调用
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        asyncResult = dele.BeginInvoke(10000015100000nullnull);
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //获取返回值
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal val = GetResult();
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine(val);
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.ReadLine(); // 让黑屏等待,不会直接关闭..
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static decimal GetResult()
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal val = 0;
21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //获取原始的委托对象:先是获取AsyncResult对象,再根据他的AsyncDelegate属性来调用
当前 的(那一个)委托对象
22什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncResult result = (AsyncResult)asyncResult;
23什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler salDel = (SalaryEventHandler)result.AsyncDelegate;
24什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
25什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //调用EndInvoke获取返回值
26什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        val = salDel.EndInvoke(asyncResult);
27什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
28什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return val;
29什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

30什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

第二种通过回调函数使用倒数第二个参数AsyncCallback 委托(public delegate void AsyncCallback(IAsyncResult ar);,建议使用这种方法.

Code 4.2

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2class  Program
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void Main(string[] args)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest test = new AsyncTest();
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler dele = test.YearlySalary;
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //异步方法开始执行,使用BeginInvoke 倒数第二个参数(AsyncCallback委托对象) ,而不用返回值
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        dele.BeginInvoke(10000015100000, GetResultCallBack, null);
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //和上面相同的
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //AsyncCallback callback = new AsyncCallback(GetResultCallBack);
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //dele.BeginInvoke(100000, 15, 100000, callback, null);
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.ReadLine(); // 让黑屏等待,不会直接关闭..
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    //必须遵循AsyncCallback 委托的定义:返回值为空,一个IAsyncResult对象参数
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void GetResultCallBack(IAsyncResult asyncResult)
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal val = 0;
21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //获取原始的委托对象
22什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncResult result = (AsyncResult)asyncResult;
23什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler salDel = (SalaryEventHandler)result.AsyncDelegate;
24什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
25什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //调用EndInvoke获取返回值
26什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        val = salDel.EndInvoke(asyncResult);
27什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
28什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine(val);
29什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

30什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

 

BeginInvoke最后一个参数是做什么的呢?我把Code 4.2 方法修改下.

Code 4.3

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2class  Program
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void Main(string[] args)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest test = new AsyncTest();
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler dele = test.YearlySalary;
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //异步方法开始执行,看最后一个参数(Object对象) [Note1:],这里我们传递2000(int)
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        dele.BeginInvoke(10000015100000, GetResultCallBack, 2000);
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.ReadLine(); // 让黑屏等待,不会直接关闭..
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void GetResultCallBack(IAsyncResult asyncResult)
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //[Note1:],他的作用就是来 "传递额外的参数",因为他本身是Object对象,我们可以传递任何对象
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        int para = (int)asyncResult.AsyncState;
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine(para);//输出:2000
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

 

异步的异常处理

接下来再讲讲EndInvoke,获取最后的返回值之外,他的一个重要的应用在引发异常来从异步操作返回异常

Code 5

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2class  Program
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void Main(string[] args)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest test = new AsyncTest();
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler dele = test.YearlySalary;
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        dele.BeginInvoke(10000015100000, GetResultCallBack, null);
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.ReadLine(); // 让黑屏等待,不会直接关闭..
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void GetResultCallBack(IAsyncResult asyncResult)
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        decimal val = 0;
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //获取原始的委托对象
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncResult result = (AsyncResult)asyncResult;
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        SalaryEventHandler salDel = (SalaryEventHandler)result.AsyncDelegate;
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        try
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            //如果EndInvoke发生异常,会在EndInvoke得到原始的异常.
21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            val = salDel.EndInvoke(asyncResult);
22什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            Console.WriteLine(val);
23什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        }

24什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        catch (Exception ex)
25什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {
26什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            Console.WriteLine(ex.Message);
27什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        }

28什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

29什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

30 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 public   delegate   decimal  SalaryEventHandler( decimal  salary,  int  monthCount,  decimal  bonus);  //  对应YearlySalary方法
31 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 public   class  AsyncTest
32 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
33什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    public decimal YearlySalary(decimal salary, int monthCount, decimal bonus)
34什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
35什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        throw new Exception("error"); //引发异常
36什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return salary * monthCount + bonus;
37什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

38什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

 

我们主动在YearlySalary方法中引发异常,BeginInvoke开始异步调用的时候捕获到了这个异常,.Net Framework会在EndInvoke得到原始的异常.

 

说到这里,大家是否可以简单的应用委托来开始自己的异步操作呢下面看看我是怎样为我自己的类添加异步的.

1类的定义,需要遵循.Net Framework 的规则

1)同步和异步是同时并存的

2)从最上面的两个委托SalaryEventHandler AsyncEventHandler生成的BeginInvoke / EndInvoke 对比中看出,我们也来定义我们自己的异步方法,我们遵循微软设计师异步方法设计的规则,Begin+同步方法名 / End+同步方法名

BeginXXX 必须返回IAsyncResult对象,后两位参数必须为AsyncCallback callback, object state,前面的参数和同步方法的参数一样

EndXXX 参数必须为IAsyncResult对象,返回值为同步方法的返回值

 

Code 6.1

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2public   class  AsyncTest
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    private delegate string AsyncEventHandler(string name);
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    private AsyncEventHandler _Async;
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    public string Hello(string name)
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return "Hello:" + name;
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    //按照.Net Framework的规则 ,编写我们自己的BeginInvoke方法
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    public virtual IAsyncResult BeginHello(string name, AsyncCallback callback, object state)
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncEventHandler del = Hello;
14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        this._Async = del;
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return del.BeginInvoke(name, callback, state);
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    //编写我们自己的EndInvoke方法
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    public virtual string EndHello(IAsyncResult asyncResult)
21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
22什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        if (asyncResult == null)
23什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            throw new ArgumentNullException("asyncResult");
24什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        if (this._Async == null)
25什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            throw new ArgumentException("_Async");
26什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
27什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        string val = string.Empty;
28什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        try
29什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {
30什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            val = this._Async.EndInvoke(asyncResult);
31什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        }

32什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        finally
33什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        {
34什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2            this._Async = null;
35什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        }

36什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        return val;
37什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

38什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

 

2调用我们编写的类

Code 6.2

 1 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2class  Program
 2 什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 {
 3什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void Main(string[] args)
 4什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
 5什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest test = new AsyncTest();
 6什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //使用回调函数,就是上面提到的"第二种"
 7什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncCallback callback = new AsyncCallback(OnHelloCallback);
 8什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        test.BeginHello("Andy Huang", callback, test);
 9什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //和上面一样
10什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //IAsyncResult result = test.BeginHello("Andy Huang", OnHelloCallback, test);
11什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
12什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.ReadLine(); // 让黑屏等待,不会直接关闭..
13什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

14什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2
15什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    static void OnHelloCallback(IAsyncResult asyncResult)
16什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    {
17什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        //获取额外的参数
18什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        AsyncTest obj = (AsyncTest)asyncResult.AsyncState;
19什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        string val = obj.EndHello(asyncResult);
20什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2        Console.WriteLine(val);
21什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2    }

22什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2}

 

引用自 :http://www.cnblogs.com/30ErLi/archive/2010/09/19/1830728.html