NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Summary of Async Design Pattern

The server splits asynchronous operation into its two logical parts: the part that takes input from the client and kicks off the asynchronous operation and the part that supplies results of the asynchronous operation to the client. In addition to the input needed for the async operation, the first part also takes an AsyncCallbackDelegate object to be called when the asynchronous operation is completed. The first part returns a waitable object that implements IAsyncResult interface used by the client to determine the status of the asynchronous operation. Server typically also utilizes the waitable object it returned to the client to maintain any state associated with asynchronous operation. The client uses the second part to obtain the results of the asynchronous operation by supplying the waitable object.

The options available to client for initiating asynchronous operations are:

  1. Supply the callback delegate when beginning asynchronous
  2. Not supply the callback delegate when beginning asynchronous operation.

The options available to the client for completing asynchronous operations are:

  1. Poll the returned IAsyncResult object for completion.
  2. Attempt to complete the operation prematurely thereby blocking until the operation completes.
  3. Wait on the IAsyncResult object. The difference between this and previous option is that the client can use timeouts to wake up periodically.
  4. Complete the operation inside the callback routine.

File IO is an example where both synchronous and asynchronous read/writes to file objects is desirable. An example of how the File object inside classlibs implements read-write operation will server as a good illustration of the design pattern.

class File
{
// Other methods
………

// Synchronous read
unsigned long Read(Byte[] buffer, unsigned long NumToRead);

// Asynchrnous read
IAsyncResult BeginRead(Byte[] buffer, 
unsigned long NumToRead, 
AsyncCallbackDelegate cb);
unsigned long EndRead(IAsyncResult ar);

// Synchronous read
unsigned long Write(Byte[] buffer, unsigned long NumToWrite);

// Asynchrnous read
IAsyncResult BeginWrite(Byte[] buffer, 
unsigned long NumToWrite, 
AsyncCallbackDelegate cb);
unsigned long EndWrite(IAsyncResult ar);

}

The client cannot easily associate state with a given asynchronous operation without defining a new callback delegate for each operation. This can be fixed by making the begin method take an extra object parameter that represents the state and which is captured into the IAsyncResult.