A Generic IAsyncResult Implementation

Lately, I've found myself writing implementations of IAsyncResult more than once, and as it turns out, all of those implementations have been so similar that I have ended up creating a generic implementation.

When implementing the Async Pattern, you can often get by with using a delegate as described in the design guidelines, and in this case, you don't need to implement IAsyncResult yourself. However, there will be cases where a custom implementation of IAsyncResult may be necessary. In some cases, the folllowing class may be suitable to your needs.

Update: Oleg Mikhailik has been so kind to point out some flaws of the code I first posted (see the comments), so I've decided to update the post with a new version of the code. Again, whether such an implementation is suitable for you depends on your needs. The main point of this post is give an example implementation of IAsyncResult, since so few are available, so this is not an authoritative, general-purpose implementation.

 internal class AsyncResult<T> : IAsyncResult, IDisposable
{
    private readonly AsyncCallback callback_;
    private bool completed_;
    private bool completedSynchronously_;
    private readonly object asyncState_;
    private readonly ManualResetEvent waitHandle_;
    private T result_;
    private Exception e_;
    private readonly object syncRoot_;
 
    internal AsyncResult(AsyncCallback cb, object state)
        : this(cb, state, false)
    {
    }
 
    internal AsyncResult(AsyncCallback cb, object state,
        bool completed)
    {
        this.callback_ = cb;
        this.asyncState_ = state;
        this.completed_ = completed;
        this.completedSynchronously_ = completed;
 
        this.waitHandle_ = new ManualResetEvent(false);
        this.syncRoot_ = new object();
    }
 
    #region IAsyncResult Members
 
    public object AsyncState
    {
        get { return this.asyncState_; }
    }
 
    public WaitHandle AsyncWaitHandle
    {
        get { return this.waitHandle_; }
    }
 
    public bool CompletedSynchronously
    {
        get 
        {
            lock (this.syncRoot_)
            {
                return this.completedSynchronously_;
            }
        }
    }
 
    public bool IsCompleted
    {
        get 
        {
            lock (this.syncRoot_)
            {
                return this.completed_;
            }
        }
    }
 
    #endregion
 
    #region IDisposable Members
 
    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }
 
    #endregion
 
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            lock (this.syncRoot_)
            {
                if (this.waitHandle_ != null)
                {
                    ((IDisposable)this.waitHandle_).Dispose();
                }
            }
        }
    }
 
    internal Exception Exception
    {
        get
        {
            lock (this.syncRoot_)
            {
                return this.e_;
            }
        }
    }
 
    internal T Result
    {
        get 
        {
            lock (this.syncRoot_)
            {
                return this.result_;
            }
        }
    }
 
    internal void Complete(T result,
        bool completedSynchronously)
    {
        lock (this.syncRoot_)
        {
            this.completed_ = true;
            this.completedSynchronously_ =
                completedSynchronously;
            this.result_ = result;
        }
 
        this.SignalCompletion();
    }
 
    internal void HandleException(Exception e,
        bool completedSynchronously)
    {
        lock (this.syncRoot_)
        {
            this.completed_ = true;
            this.completedSynchronously_ =
                completedSynchronously;
            this.e_ = e;
        }
 
        this.SignalCompletion();
    }
 
    private void SignalCompletion()
    {
        this.waitHandle_.Set();
 
        ThreadPool.QueueUserWorkItem(new WaitCallback(this.InvokeCallback));
    }
 
    private void InvokeCallback(object state)
    {
        if (this.callback_ != null)
        {
            this.callback_(this);
        }
    }
}

As reproduced here, you may have noticed that the class is internal. This is because I usually just copy in this code and use it internally, but if you want to include it in a reusable library, you will obviously need to change the class and relevant members (the constructors, Result and Complete) to public.

When implementing the Async Pattern, you can create and return an instance of AsyncResult<T> and return it from your BeginX method. Then, when your asynchronous operation completes, call the Complete method, which will store the result, release the WaitHandle and invoke any callback supplied by the client. To implement the EndX method, cast the incoming IAsyncResult to AsyncResult<T>, call WaitOne on its AsyncWaitHandle and return its Result property.

This is not the only way to implement IAsyncResult, but it has worked well for me in several cases.