Skip to content

Instantly share code, notes, and snippets.

@hidori
Created January 8, 2015 14:01
Show Gist options
  • Save hidori/5e3794757e0db5c7ef08 to your computer and use it in GitHub Desktop.
Save hidori/5e3794757e0db5c7ef08 to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
namespace Mjollnir
{
public class AsyncResult : IAsyncResult, IDisposable
{
public AsyncResult(AsyncCallback callback, object state)
{
// callback can be null.
// state can be null.
this.callback = callback;
this.state = state;
}
~AsyncResult()
{
try
{
this.Dispose(false);
}
catch
{
// ignore.
}
}
public void Completed()
{
this.ThrowIfDisposed();
lock (this.syncRoot)
{
this.isCompleted = true;
// this.completedSynchronously should be false.
}
this.waitHandle.Set();
if (this.callback != null)
{
this.callback(this);
}
}
public void CompletedSynchronously()
{
this.ThrowIfDisposed();
lock (this.syncRoot)
{
this.isCompleted = true;
this.completedSynchronously = true;
}
this.waitHandle.Set();
if (this.callback != null)
{
this.callback(this);
}
}
#region IDisposable
bool disposed = false;
protected bool IsDisposed
{
get { return this.disposed; }
}
protected virtual void Dispose(bool disposing)
{
if (this.disposed) return;
if (disposing)
{
this.waitHandle.Dispose();
}
}
protected void ThrowIfDisposed()
{
if (this.disposed) throw new System.ObjectDisposedException(this.GetType().Name);
}
protected void ThrowIfDisposed(string message)
{
if (message == null) throw new System.ArgumentNullException("message");
if (this.disposed) throw new System.ObjectDisposedException(this.GetType().Name, message);
}
void System.IDisposable.Dispose()
{
try
{
this.Dispose(true);
}
catch
{
// ignore.
}
GC.SuppressFinalize(this);
this.disposed = true;
}
#endregion
#region IAsyncResult
readonly object syncRoot = new object();
readonly AsyncCallback callback;
readonly object state;
readonly ManualResetEvent waitHandle = new ManualResetEvent(false);
volatile bool isCompleted = false;
volatile bool completedSynchronously = false;
public object AsyncState
{
get { return this.state; }
}
WaitHandle IAsyncResult.AsyncWaitHandle
{
get { return this.waitHandle; }
}
bool IAsyncResult.CompletedSynchronously
{
get
{
lock (this.syncRoot)
{
return this.completedSynchronously;
}
}
}
bool IAsyncResult.IsCompleted
{
get
{
lock (this.syncRoot)
{
return this.isCompleted;
}
}
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment