转载地址:http://www.xc369.com/viewthread.php?tid=26272
在学习回调与异步调用之前,让我们先回顾一下最基本的同步调用。同步调用是一种阻塞式的调用,在模块A调用模块B时,A要等待B返回结果才能继续执行。这种模式就好比是打电话,当电话接通以后。双方就是一种同步的关系,只要你们继续对话,两人的电话线路就必须处于连接状态。而异步关系,则很像是我们平时使用QQ,会话双方不需要保持连接,其中一方可能不在线,但仍可以发送消息。等他上线以后方可收到消息。在这个过程中你既可以给其他人发消息,其他人也可以给你发消息,不存在“占线”或“线路忙”等阻塞模式的一些特点。
理解了同步和异步的关系。在来理解异步调用,就容易许多了。异步调用就是调用方(A)在调用了被调用(B)后,不需要等待(B)返回结果,仍可以继续执行(A)中的其他代码。而当(B)处理完返回结果给(A)时,(A)的异步处理机制可以接收到这种消息并采取相应的措施。
回调则是实现这种模式最简单的机制。当(A)调用(B)后,(B)在执行到某个环节时需要调用(A)。也就是被调用的模块在特定情况时会成为调用模块,反过来调用(A),此时原来调用的模块又变为被调用方。当(A)将结果返回给(B)后,(B)在继续执行剩下的指令,然后将结果返回给(A)从而完成这次调用。其实看图来理解回调可能更容易一下,如下图
也就是在一般的调用过程中多两个环节,如粉红色箭头。上一个箭头就是回调,Callback。
在Windows应用程序中,大量使用了这种调用机制。如窗口事件与事件处理。windows提供了触发事件和执行事件处理的机制,但如何处理则交给应用程序的开发人员来设计。这个开发人员所定置的事件处理程序就是发生回调时被调用的模块(但这个模块取位于主调模块中)。
请看一个代码片段:
1 public class HelloCallBack:System.Windows.Forms.Form
2 {
3
private Button buttonOK;
4
5
private void InitObject()
6 {
7 buttonOK = new System.Windows.Forms.Button();
8
9 buttonOK.Click +=new EventHandler(buttonOK_Click);
10
11
this.Controls.Add(buttonOK);
12 }
13
14 buttonOK_Click(object sender, EventArgs e)
15 {
16 MessageBox(“Hello CallBack”,Message”);
17 }
18
19
public static void Main()
20 {
21 Application.Run( new HelloCallBack() );
22 }
23 }
24
这是一个.NET 下的Windows应用程序的部分代码。非常简单,就是有个按扭,你点了之后会弹出个对话框,上面显示Hello CallBack. 但却十分典型的体现了.NET下的回调与异步调用模式。
我们可以简单的把这个类(HelloCallBack)理解为主调模块A,当你点了这个窗口内的按扭OK之后。你就调用另一个模块(EventHandler里关于触发Button被单击事件的相关逻辑),而这个时候EventHandler不是执行完然后返回给HelloCallBack,而是反过来调用HelloCallBack里的buttonOK_Click()方法用于执行这一事件该具体如何处理的逻辑。待这个方法执行完后,EventHandler完成剩下的工作并将结果返回给HelloCallBack。
.NET 提供了委托这种回调机制,通过重载+(-)和+=(-=)作符来注册(注销)委托或事件。事件本质上就是一种委托。