25.2 BeginInvoke和EndInvoke

在C#中使用线程的方法很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一。在讲这两个方法之前,先来大致看一下这两个方法的用法,如代码清单25-1所示。

代码清单25-1 异步调用的一段示例代码


//声明一个委托类型

public delegate void PrintDelegate(string content);

//定义一个委托要代理的方法

public static void Print(string content)

{

Console.WriteLine(“打印中……\n{0}”,content);

System.Threading.Thread.Sleep(2000);

}

//将目标方法添加到委托的方法列表里去

PrintDelegate printDelegate=AsynchronousSample.Print;

//调用委托的BeginInvoke方法,开始异步调用委托列表中的目标方法

IAsyncResult result=printDelegate.BeginInvoke("Hello World!",null,null);

//调用委托的EndInvoke方法,等待异步调用结束

printDelegate.EndInvoke(result);


看了上面的代码,是否对于这两个方法的应用有了一个初步的了解?要说明的是,这只是异步调用的方法之一,稍后还会讲到更多的方法。接下来,我们将对这两个方法进行详细阐述。

BeginInvoke方法可以使用线程异步地执行委托所指向的方法。需要特别强调的是,委托所代理的目标方法只能为1个。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用,这取决于采用何种异步编程的方法。

我们在第15章学习了委托,知道我们定义的委托实际上派生自System.MulticastDelegate,后者是一个抽象类,它又继承自System.Delegate类,如果大家查阅这两个类的API文档会发现根本没有BeginInvoke、EndInvoke这两个方法,但是Visual Studio 2010的IntelliSense功能却提示了这两个方法,包括参数说明,如图25-3所示。

25.2 BeginInvoke和EndInvoke - 图1

图 25-3 Visual Studio 2010中对BeginInvoke的代码提示

事实上,这两个方法并不存在于这些委托的基类中,而是在编译期间由编译器加入的。

需要说明的是,在其他的.NET Framework类中也有类似BeginInvoke和EndInvoke的方法,如System.IO.FileStream类的BeginRead和EndRead方法,以及BeginWrite和EndWrite方法。这里就不再举例子了,大家可以参考26.3节。