|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace FastInvoke
{
public delegate T FastInvokeDelegate<T>();
public static class DelegateExtensions
{
public static IAsyncResult BeginInvokeFast<T>(this FastInvokeDelegate<T> del, object state, AsyncCallback callback)
{
return new FastInvokeAsyncResult<T>(del, callback, state);
}
public static T EndInvokeFast<T>(this FastInvokeDelegate<T> del, IAsyncResult asyncResult)
{
var result = asyncResult as FastInvokeAsyncResult<T>;
if (result == null)
throw new InvalidOperationException("Wrong async result");
return result.End();
}
private class FastInvokeAsyncResult<T> : IAsyncResult
{
private volatile int m_isCompleted; // 0==not complete, 1==complete.
private ManualResetEvent m_asyncWaitHandle;
private volatile int m_asyncWaitHandleNeeded = 0; //0 - is not needed, 1 - needed
private readonly AsyncCallback m_callback;
private readonly object m_asyncState;
// To hold the results, exceptional or ordinary.
private Exception m_exception;
private T m_result;
public FastInvokeAsyncResult(FastInvokeDelegate<T> work, AsyncCallback callback, object state)
{
m_callback = callback;
m_asyncState = state;
Run(work);
}
public bool IsCompleted
{
get { return (m_isCompleted == 1); }
}
public bool CompletedSynchronously
{
get { return false; }
}
public WaitHandle AsyncWaitHandle
{
get
{
if (m_asyncWaitHandleNeeded == 1)
{
return m_asyncWaitHandle;
}
m_asyncWaitHandleNeeded = 1;
m_asyncWaitHandle = new ManualResetEvent(m_isCompleted == 1);
return m_asyncWaitHandle;
}
}
public object AsyncState
{
get { return m_asyncState; }
}
private void Run(FastInvokeDelegate<T> work)
{
ThreadPool.QueueUserWorkItem(delegate
{
try
{
m_result = work();
}
catch (Exception e)
{
m_exception = e;
}
finally
{
m_isCompleted = 1;
if (m_asyncWaitHandleNeeded == 1)
{
m_asyncWaitHandle.Set();
}
if (m_callback != null)
m_callback(this);
}
});
}
public T End()
{
if (m_isCompleted == 0)
{
AsyncWaitHandle.WaitOne();
AsyncWaitHandle.Close();
}
if (m_exception != null)
throw m_exception;
return m_result;
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
The views expressed in my articles are mine and do not necessarily reflect the views of my employer.
if(youWantToContactMe)
{
SendMessage(string.Format("{0}@{1}.com", "liptchinski_vit", "yahoo"));
}
More info in my LinkedIn profile:
http://www.linkedin.com/in/vitaliyliptchinsky