在上一篇文章(什么是.Net的异步机制(Invoke,BeginInvoke,EndInvoke) - step 2 ), 我们已经简单介绍了异步的调用方式, 下面我们来看看异步的核心.
异步的核心: IAsyncResult
Asynchronous Programming Model
整个异步调用过程中都是围绕IAsyncResult来进行的,大家可以看看上篇文章的例子,BeginXXX 返回这个对象,EndXXX接收这个对象来结束当前异步对象,下面我们来看看IAsyncResult 接口成员/和实现此接口的AsyncResult类成员(其中有些在上篇中已经涉及到)
IAsyncResult接口
1
public
interface
IAsyncResult
2
{
3
WaitHandle AsyncWaitHandle
{ get; } //阻塞一个线程,直到一个或多个同步对象接收到信号
4
Boolean IsCompleted
{ get; } //判读当前异步是否完成
5
Object AsyncState
{ get; } //获取额外的参数值,请看上一篇文章的Code 4.3
6
Boolean CompletedSynchronously
{ get; } //几乎没有使用
7
}

2



3



4



5



6



7

AsyncResult类
1
public
class
AsyncResult : IAsyncResult, IMessageSink
2
{
3
//IAsyncResult 的实现
4
public virtual WaitHandle AsyncWaitHandle
{ get; }
5
public virtual bool IsCompleted
{ get; }
6
public virtual object AsyncState
{ get; }
7
public virtual bool CompletedSynchronously
{ get; }
8
9
// 其他一些重要的属性
10
public bool EndInvokeCalled
{ get; set; } //检验是否调用了EndInvoke()
11
public virtual object AsyncDelegate
{ get; } //获取原始的委托对象,可查看上一篇文章中的Code 4.1/4.2/5
12
}

2



3

4



5



6



7



8

9

10



11



12

注意:基本上都是只读属性
下面我们来看看异步的执行顺序,并回顾下 IAsyncResult 下各个属性的应用,如果还是不熟悉请看前2篇文章.
Code 1:
1
class
Program
2
{
3
static void Main(string[] args)
4
{
5
Console.WriteLine("[(#{1}){0}]:Asynchronous Start", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
6
7
AsyncTest test = new AsyncTest();
8
MyThirdAsyncCode.AsyncTest.SalaryEventHandler del = test.YearlySalary;
9
//使用回调函数
10
AsyncCallback callback = new AsyncCallback(OnSalaryCallback);
11
IAsyncResult ar = del.BeginInvoke(100000, 15, 100000, callback, 2000);
12
13
DoAntherJob();
14
Console.ReadLine(); // 让黑屏等待,不会直接关闭..
15
}
16
17
//开始其他工作.
18
static void DoAntherJob()
19
{
20
Thread.Sleep(1000);//需要1秒才能完成这个工作,注1
21
Console.WriteLine("[(#{1}){0}]:Do Another Job", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
22
}
23
24
static void OnSalaryCallback(IAsyncResult asyncResult)
25
{
26
//通过AsyncState 获取额外的参数.
27
decimal para = (int)asyncResult.AsyncState;
28
29
//通过AsyncDelegate 获取原始的委托对象
30
AsyncResult obj = (AsyncResult)asyncResult;
31
MyThirdAsyncCode.AsyncTest.SalaryEventHandler del =
(MyThirdAsyncCode.AsyncTest.SalaryEventHandler)obj.AsyncDelegate;
32
33
if (asyncResult.IsCompleted)// 判读是否已经调用完成
34
Console.WriteLine("[(#{1}){0}]:Asynchronous Finished.", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
35
36
decimal val = del.EndInvoke(asyncResult);
37
38
Console.WriteLine("[(#{2}){0}]:Output Result:{1}", DateTime.Now.ToString(), val + para, Thread.CurrentThread.ManagedThreadId);
39

2



3

4



5

6

7

8

9

10

11

12

13

14

15

16

17

18

19



20

21

22

23

24

25



26

27

28

29

30

31

(MyThirdAsyncCode.AsyncTest.SalaryEventHandler)obj.AsyncDelegate;
32

33

34

35

36

37

38

39