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!

Thread Pool HowTo

Queue a request to the Thread Pool

Class Library code -Perform BeginEnd and do EndRead on AsyncCallback

User Code

//---------------------------------------------------------------
// User code
//
// This is the code the application user will write
//
// Untrusted
//

class Foo
{
  //. . .
  // This AsyncCallback is called when IO Operations 
  // complete asynchronously and are queued via 
  // a thread pool thread
  //
  public void UserCallback(IAsyncResult ar)
  {
    // Extract AsyncFileStream from AsyncResult
    AsyncFileStream f = 
                (AsyncFileStream)ar.AsyncObject;
                
    // End the Read call
    int bytesRead = f.EndRead(ar);
    
    // do something with the bytes read 
    // and data in the byte array ‘b’
    //. . .
  }

  // The user opens the file in async and 
  // issues an async read operation
  //

  public void Method2()
  {
    //. . .
    byte [] b;
    // Open the file in async mode
    AsyncFileStream f = File.OpenAsync("foo");

    //
    // The user can store any object they choose
    //
    Object state  = SomeUserStateObject;
       
    // Create new delegate
    // This delegate could be to a static method
    // This delegate could be shared across multiple
    // async calls
    //
    AsyncCallback ac = new AsyncDelegate(
                            this.UserCallback
                            );
    //Issue async read - pass byte array & size
    IAsyncResult ar = F.BeginRead (
                        b,
                        10,
                        ac,
                        state);
  }
  //. . .
}

Class Library code

File

//---------------------------------------------------------------
// This is code the class library writers could write.
//
// e.g. Async File Stream Code
//
// PInvoke capability needed
//
class File
{
  //. . .
  public static AsyncFileStream OpenAsync(String name)
  {
    //. . .
    // Open the file in Async mode
    AsyncFileStream f = new AsyncFileStream(name);
    //. . .
    return f;
  }
  //. . .
}

Async File Stream Async Result

// This is a async file stream class library specific AsyncResult
// The class library writer could hold any state they choose
// in the AsyncResult e.g. userCallback
//
class AsyncFileStream_AsyncResult : IAsyncResult
{
  //. . .

  // User code callback
  public AsyncCallback userCallback;

  // Regular fields
  public Object asyncObject;
  public Object userStateObject;

  //. . .

  // Regular IAsyncResult methods
  public Object AsyncObject  
  {
      virtual get
      {
          return asyncObject;
      }
  }

  public Object AsyncState
  {
      virtual get
      {
          return userStateObject;
      }
  }
  //. . .
}

Async File Stream

class AsyncFileStream
{ 
  // This callback is called by COR when the IO operation completes 
  // asynchronously and is queued via the thread pool
  //
  public static bool AsyncClassLibraryCallback(
    UInt32 errorCode, 
    UInt32 numBytes, 
    NativeOverlapped *pOVERLAP)
  {
     // Unpack overlapped
     Overlapped overlapped = Overlapped.Unpack(pOVERLAP);

     // Extract async result from overlapped 
     AsyncFileStream_AsyncResult ar = 
             (AsyncFileStream_AsyncResult)Overlapped.AsyncResult
              
    // Extract user callback from AsyncResult
    // then invoke user callback and pass in AsyncResult
    AsyncCallback ac = ar.userCallback;
    ac.Invoke(ar);
  }

  // Construct a new Async File Stream
  //
  public AsyncFileStream(String name)
  {
    //. . .
    // Open the file in Overlapped mode
    //
    int handle = Win32.CreateFile(
                  //. . .
                  FILE_FLAG_OVERLAPPED
                  //. . .
                  );

    IOCompletionCallback iocb = new IOCompletionCallback(
                   AsyncFileStream.AsyncClassLibraryCallback
                             );
                                       
    // Bind OS Handle with classLibrary Callback
    bool b = ThreadPool.BindHandleWithCallback(
                  handle,
                  );
    //. . .
  }

  // Async BeginRead operation
  //
  public IAsyncResult BeginRead(
                  byte[] b, 
                  int size, 
                  AsyncCallback cb, 
                  Object stateObject)
  {
    // Make a new delegate
    IOCompletionCallback iocb = 
      new IOCompletionCallback(
       AsyncFileStream.AsyncClassLibraryCallback
      );

    // Create and store async stream class library specific data in the 
    // async result
    AsyncFileStream_AsyncResult ar = new AsyncFileStream_AsyncResult();
    ar.asyncObject = this;
    ar.userCallback = cb;
    ar.userStateObject = stateObject;

    // Create a managed overlapped class
    Overlapped overlapped = new Overlapped(0,0,0,ar);

    //. . .
    // Pack the Overlapped class
    NativeOverlapped *pOVERLAP = overlapped.Pack(iocb);

    // queue an async ReadFile operation and pass in
    // packed overlapped
    Win32.ReadFile(
           //. . .
           pOVERLAP,
           //. . .
        )
  }

  // Async EndRead operation
  //
  // Returns the number of bytes read
  //
  public int EndRead (IAsyncResult ar)
  {
    //. . .

    //. . .
  }  
  //. . .
}