如果服务器需要花费一段时间才能完成,那么客户端就需要做不同的工作,没必要启动一个单独线程去进行远程调用,那么就可以进行异步调用。
为实现异步,要创建一个相同参数的委托(指客户机调用的远程对象上的Getting()方法),它将返回远程对象的此Getting()方法。使用委托的BeginInvoke()方法可以调用该Getting()方法。BeginInvoke()的第二个参数AsyncCallback()实例,该实例定义了客户机上的方法Callback()。当远程方法完成时,会自动调用Callback()。在Callback()方法中,远程调用的是使用EndInvoke()完成的。BeginInvoke()用于启动异步,使用IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。然后对象接收EndInvoke(),异步完成。
如下,假如远程对象有方法:GetName(string name)
class Class1
{
//异步调用,必须定义委托
private delegate string getNameDelegate(string name);
private static string getName;
/// <summary>
/// 应用程序的主入口点。必须引用代理装配件RemotingHello,
/// </summary>
[STAThread]
static void Main(string[] args)
{
ChannelServices.RegisterChannel(new TcpClientChannel());
//创建代理类
Hello obj=(Hello)Activator.GetObject
(typeof(Hello),"tcp://localhost:8086/Hi");
getNameDelegate gd=new getNameDelegate(obj.getName);
//用于启动异步,返回IasyncResult,可用于监视调用进度
IAsyncResult ar=gd.BeginInvoke(" 风云",null,null);
//使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,
//使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。
//做其他工作,也就是不是当前线程。等待服务器远程对象的返回
ar.AsyncWaitHandle.WaitOne();
//EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke
//后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke
//将一直阻塞到异步调用完成。
//判断是否已经完成
if(ar.IsCompleted)
{
getName=gd.EndInvoke(ar);
}
Console.WriteLine(getName);
}
{
//异步调用,必须定义委托
private delegate string getNameDelegate(string name);
private static string getName;
/// <summary>
/// 应用程序的主入口点。必须引用代理装配件RemotingHello,
/// </summary>
[STAThread]
static void Main(string[] args)
{
ChannelServices.RegisterChannel(new TcpClientChannel());
//创建代理类
Hello obj=(Hello)Activator.GetObject
(typeof(Hello),"tcp://localhost:8086/Hi");
getNameDelegate gd=new getNameDelegate(obj.getName);
//用于启动异步,返回IasyncResult,可用于监视调用进度
IAsyncResult ar=gd.BeginInvoke(" 风云",null,null);
//使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,
//使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。
//做其他工作,也就是不是当前线程。等待服务器远程对象的返回
ar.AsyncWaitHandle.WaitOne();
//EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke
//后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke
//将一直阻塞到异步调用完成。
//判断是否已经完成
if(ar.IsCompleted)
{
getName=gd.EndInvoke(ar);
}
Console.WriteLine(getName);
}