C#可以有一个简单易用的机制用于异步执行方法,那就是委托。下面我介绍三种模式,对于这三种模式来说,原始线程都发起了一个异步方法,然后做一些其他处理。然而这些模式不同的是,原始线程获取发起的线程已经完成的消息的方式。
1:在等待一直到完成(wait-nutil-done)模式。
在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等异步方法完成之后再继续。
1
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 |
class
Program { private
delegate int MyDel( int
a); public
static int MyMenthod( int
a) { for
( int
i = 0; i < 1000; i++) { a++; } return
a; } static
void Main( string [] args) { var
del = new
MyDel(MyMenthod); Console.WriteLine( "Before BeginInvoke" ); IAsyncResult iar = del.BeginInvoke(5, null , null ); Console.WriteLine( "After BeginInvoke" ); Console.WriteLine( "Doing stuff" ); long
result = del.EndInvoke(iar); Console.WriteLine( "结果为{0}" ,result); } } |
运行结果为
2:轮询模式(polling)。
原始线程定期检查发起的线程是否完成,如果没有则可以继续做其他的事情。上代码
1
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
32
33 |
class
Program { private
delegate int MyDel( int
a); public
static int MyMenthod( int
a) { for
( int
i = 0; i < 1000; i++) { a++; } Thread.Sleep(3000); return
a; } static
void Main( string [] args) { var
del = new
MyDel(MyMenthod); IAsyncResult iar = del.BeginInvoke(5, null , null ); Console.WriteLine( "After BeginInvoke" ); while
(!iar.IsCompleted) { Console.WriteLine( "还没处理完" ); Thread.Sleep(2000); Console.WriteLine( "继续处理其他事情" ); } Console.WriteLine( "异步执行完成" ); long
result = del.EndInvoke(iar); Console.WriteLine( "结果为{0}" ,result); } } |
运行结果为:
3:回调模式(callbacl)。
原始线程一直执行,无需等待或检查发起的线程是否完成,在发起的线程中的引用方法完成之后,发起的线程就会调用回调方法,由回调方法在调用EndInvoke之前处理异步方法的结构。上代码
1
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 |
class
Program { private
delegate int MyDel( int
a); public
static int MyMenthod( int
a) { for
( int
i = 0; i < 1000; i++) { a++; } return
a; } public
static void CallBack(IAsyncResult iar) { AsyncResult ar = iar as
AsyncResult; MyDel del = (MyDel)ar.AsyncDelegate; long
r = del.EndInvoke(iar); Thread.Sleep(2000); Console.WriteLine( "结果出来了,为{0}" , r); } static
void Main( string [] args) { var
del = new
MyDel(MyMenthod); Console.WriteLine( "After BeginInvoke" ); IAsyncResult iar= del.BeginInvoke(5, CallBack, del); Console.WriteLine( "Doing More Work In Main" ); Thread.Sleep(5000); } } |
运行结果为:
回调方法的签名和返回类型必须和AsyncCallbacl委托类型所描述的形式一致。它需要方法接受一个IAsyncResult作为参数并且返回类型是void,如下:
void AsyncCallback(IAsyncResult iar)
我们有多种方式可以为BeginInvoke方法提供回调方法,由于BeginInvoke中的callback参数是AsyncCallback类型的委托,我们可以以委托形式提供,我们也可以只提供回调方法名称,让编译器为我们创建委托,两种形式是等价的。
IAsyncResult iar1 = del.BeginInvoke(5,new AsyncCallback(CallWhenDone),null);
IAsyncResult iar2 = del.BenginInvoke(5,CallWhenDone,null);
C#每天进步一点--异步编程模式,布布扣,bubuko.com
原文:http://www.cnblogs.com/zb-success/p/3661074.html