In my last post I talked about the WCF async programming model. On the service side you have to create a custom implementation of IAsyncResult. Fortunately this turns out to be pretty much boilerplate code so here is a general purpose one
class
UniversalAsyncResult : IAsyncResult, IDisposable
{
// To store the callback and state passed
AsyncCallback callback;
object state;
// For the implementation of IAsyncResult.AsyncCallback
volatile ManualResetEvent waithandle;
// Guard object for thread sync
object guard = new object();
// complete flag that is set to true on completion (supports IAsyncResult.IsCompleted)
volatile bool complete;
// Store the callback and state passed
public UniversalAsyncResult(AsyncCallback callback, object state)
{
this.callback = callback;
this.state = state;
}
// Called by consumer to set the call object to a completed state
public void Complete()
{
// flag as complete
complete = true;
// signal the event object
if (waithandle != null)
{
waithandle.Set();
}
// Fire callback to signal the call is complete
if (callback != null)
{
callback(this);
}
}
#region IAsyncResult Members
public object AsyncState
{
get { return state; }
}
// Use double check locking for efficient lazy allocation of the event object
public WaitHandle AsyncWaitHandle
{ get
{
if (waithandle == null)
{
lock (guard)
{
if (waithandle == null)
{
waithandle = new ManualResetEvent(false);
// guard against the race condition that the waithandle is
// allocated during or after complete
if( complete )
{
waithandle.Set();
}
}
}
}
return waithandle;
}
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return complete; }
}
#endregion
#region IDisposable Members
// Clean up the event if it got allocated
public void Dispose()
{
if (waithandle != null)
{
waithandle.Close();
}
}
#endregion
}
You create an instance of UniversalAsyncResult passing in an AsyncCallback and state object if available. When you have finished your async processing just call the Complete method on the UniversalAsyncResult object.
Comments welcome