Asynchronous Message Processing

The .NET Remoting infrastructure processes asynchronous method calls by invoking the IMessageSink.AsyncProcessMessage method. Unlike SyncProcessMessage, AsyncProcessMessage doesn't process both the request and response messages. Instead, AsyncProcessMessage processes the request message and returns. Later, when the asynchronous operation completes, the .NET Remoting infrastructure (ironically) passes the response message to the IMessageSink.SyncProcessMessage method of the sink referenced by the second parameter to the AsyncProcessMessage method, replySink. If you need to process the response message of an asynchronous call, you must add a message sink to the front of the replySink chain prior to passing the request message to the next sink in the chain.

To facilitate implementing AsyncProcessMessage, we've defined a helper class named AsyncReplyHelperSink that takes a delegate to a callback method that it invokes upon receiving an IMessage in SyncProcessMessage:

// Generic AsyncReplyHelperSink class - delegates calls to // SyncProcessMessage to delegate instance passed in ctor.

public class AsyncReplyHelperSink : IMessageSink {

// Define a delegate to the callback method.

public delegate IMessage AsyncReplyHelperSinkDelegate(IMessage msg);

IMessageSink _NextSink;

AsyncReplyHelperSinkDelegate _delegate;

public System.Runtime.Remoting.Messaging.IMessageSink NextSink {

return _NextSink;

public AsyncReplyHelperSink( IMessageSink next,

AsyncReplyHelperSinkDelegate d )

public virtual IMessage SyncProcessMessage (IMessage msg ) {

// Notify delegate of reply message. The delegate // can modify the message, so save the result and // pass it down the chain. IMessage msg2 = _delegate(msg); return _NextSink.SyncProcessMessage(msg2);

return new ReturnMessage( new System.Exception(

"AsyncProcessMessage _delegate member is null!"), (IMethodCallMessage)msg );

public virtual IMessageCtrl AsyncProcessMessage (

System.Runtime.Remoting.Messaging.IMessage msg , System.Runtime.Remoting.Messaging.IMessageSink replySink )

// This should not be called in the reply sink chain. The // runtime processes reply messages to asynchronous calls // synchronously. Someone must be trying to use us in a // different chain! return null;

The PassThruMessageSink class uses the helper class by instantiating a delegate that targets its AsyncProcessRepIyMessage method, passing the delegate to a new instance of the helper class, and adding the instance of the helper class to the reply sink chain. We'll use the AsyncRepIyHeIperSink class in several examples in the next section.

0 0

Post a comment