How Do I...Make an Asynchronous Call to a Remote Object?
All the examples up to this point made synchronous calls to the remote
object. This strategy might not always be desirable since the remote
object might have to perform a number of time-consuming tasks and it is
not advisable to block the client while a call is in progress. This example demonstrates how to make asynchronous calls.
Reuse the server from the hello sample and modify the client to make
asynchronous calls. The following code example demonstrates the new client code.
using System;
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();
}
}
}
C#
An Event object is used to prevent the client application from returning
from Main while the asynchronous call is pending. You need to reset the Event object
to false on the first line in Main and wait for state of the object to change
before leaving Main.
The async programming pattern in the .NET Framework requires a delegate to
represent the callback function. You need to declare the delegate that is required before it
can be used. Delegates are somewhat similar to function pointers on classes
in C++. You have to declare a delegate with the same calling parameters and result type
as the method the delegate represents. Since you need to define a delegate for the
HelloMethod you want to call, declare the delegate as follows:
public delegate String MyDelegate(String name);
C#
The call accepts a string as argument and returns a string as the result.
The compiler automatically generates the class MyDelegate when it
encounters the declaration and adds a BeginInvoke and EndInvoke method to
the delegate that maps to native calls somewhere in the common language runtime.
The next is to create the
callback function that receives the result from the call.
public static void MyCallBack(IAsyncResult ar) {
MyDelegate d = (MyDelegate)((AsyncResult)ar).AsyncDelegate;
Console.WriteLine(d.EndInvoke(ar));
e.Set();
}
C#
Notice how the callback declares an object of type IAsyncResult as the
parameter of the callback function. Once the call completes, the
framework ensures that the result of the call is placed inside
the result object and the callback is then invoked back
to the client, forwarding the result object to it. To retrieve
the result of the call, extract the delegate
from the AsyncResult and call EndInvoke.
The following code example demonstrates calling the HelloMethod on the remote object.
AsyncCallback cb = new AsyncCallback(Client.MyCallBack);
MyDelegate d = new MyDelegate(obj.HelloMethod);
IAsyncResult ar = d.BeginInvoke("Caveman", cb, null);
C#
Create a delegate for the callback method and one for the remote
method. Next, call the method by calling BeginInvoke on the delegate,
and wait for the result to return from the server.
VB Async calls
[This sample can be found at D:\inetpub\wwwroot\quickstart.developerfusion.co.uk\QuickStart\HowTo\Samples\Remoting\async\]
Microsoft .NET Framework SDK QuickStart Tutorials Version 2.0
Copyright � 2004 Microsoft Corporation. All rights reserved.
|