原文出处:http://lmarsy.bokee.com/1226434.html
如何对远程对象进行异步调用
此刻之前的所有示例都对远程对象进行同步调用。这种策略可能并非始终合乎需要,因为远程对象可能必须执行大量耗时的任务,而且在调用处于进行中时阻塞客户端是不明智的举措。此示例演示如何进行异步调用。
重用 hello 示例的服务器并修改客户端以进行异步调用。下面的代码示例演示新客户端代码。
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace RemotingSamples {
public class Client {
public static ManualResetEvent e;
public delegate String MyDelegate(String name);
public static int Main( string [] args) {
e = new ManualResetEvent( false );
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
HelloServer obj = (HelloServer)Activator.GetObject(
typeof (RemotingSamples.HelloServer),
" tcp://localhost:8085/SayHello " );
if (obj == null ) System.Console.WriteLine( " Could not locate server " );
else {
AsyncCallback cb = new AsyncCallback(Client.MyCallBack);
MyDelegate d = new MyDelegate(obj.HelloMethod);
IAsyncResult ar = d.BeginInvoke( " Caveman " , cb, null );
}
e.WaitOne();
return 0 ;
}
public static void MyCallBack(IAsyncResult ar) {
MyDelegate d = (MyDelegate)((AsyncResult)ar).AsyncDelegate;
Console.WriteLine(d.EndInvoke(ar));
e.Set();
}
}
}
Event 对象用于防止在异步调用挂起时客户端应用程序从 Main 返回。需要在 Main 的第一行将 Event 对象重置为假,并等到该对象的状态更改后才能离开 Main。 .NET Framework 中的异步编程模式需要一个"代理"来表示回调函数。需要先声明所需的代理,然后才能使用它。委托有点类似于 C++ 中类上的函数指针。必须使用与委托所表示的方法相同的调用参数和结果类型来声明该委托。因为需要为要调用的 HelloMethod 定义一个委托,所以按如下所示声明该委托:
该调用接受字符串作为参数,并返回字符串作为结果。当编译器遇到该声明时,它自动生成类 MyDelegate,并将 BeginInvoke 和 EndInvoke 方法添加到该委托中,该委托映射到公共语言运行库中某处的本机调用。 下列是创建接收调用结果的回调函数的代码。
MyDelegate d = (MyDelegate)((AsyncResult)ar).AsyncDelegate;
Console.WriteLine(d.EndInvoke(ar));
e.Set();
}
请注意回调是如何将 IAsyncResult 类型的对象声明为回调函数的参数的。调用完成后,框架确保调用的结果放置在结果对象内,然后将回调调用回客户端,将结果对象转发给客户端。若要检索调用的结果,请从 AsyncResult 解压缩委托,然后调用 EndInvoke。 下面的代码示例演示对远程对象调用 HelloMethod。
MyDelegate d = new MyDelegate(obj.HelloMethod);
IAsyncResult ar = d.BeginInvoke( " Caveman " , cb, null );
为 callback 方法和 remote 方法分别创建一个委托。然后,通过对该委托调用 BeginInvoke 来调用方法,然后等待自服务器返回的结果。