/// <summary> /// A lambda Action and the maximum waiting time in the filum are passed to it by parameter. /// </summary> /// <param name="action">Action passed as a lambda expression</param> /// <param name="milisecondsTimeOut">Blocks the current thread until the current WaitHandle (mPeekCompleteWaitHandle) receives a signal, /// using a 32-bit signed integer to specify the time interval in milliseconds. /// </param> public void Send(Action action, int milisecondsTimeOut = -1) { // Dispatches an asynchronous message to context SendOrPostCallback d = new SendOrPostCallback(_ => action()); // create an item SendOrPostCallbackItem item = new SendOrPostCallbackItem(d); // Add item to the filum mFilum.AddItem(item); // Wait for the item add to peek if (item.mPeekCompleteWaitHandle.WaitOne(milisecondsTimeOut)) { item.mExecutionCompleteWaitHandle.WaitOne(); // <-- Wait for the item execution to end } else { mFilum.RemoveItem(item); // <-- Waiting Time is out } // throw the exception on the caller thread, not the STA thread. if (item.mExecutedWithException) { throw item.mException; } }
public override void Post(SendOrPostCallback d, object state) { // queue the item and don't wait for its execution. This is risky because // an unhandled exception will terminate the STA thread. Use with caution. SendOrPostCallbackItem item = new SendOrPostCallbackItem(d, state, ExecutionType.Post); mQueue.Enqueue(item); }
public void AddItem(SendOrPostCallbackItem item) { lock (((ICollection)mQueue).SyncRoot) { mQueue.Enqueue(item); mItemsInQueueEvent.Set(); } }
/// <summary> /// Executing any work items on the Run method means executing them on the STA thread. /// </summary> private void Run() { while (true) { bool stop = mStopEvent.WaitOne(0); if (stop) { break; } SendOrPostCallbackItem workItem = mFilumPunter.Peek(); if (workItem != null) { workItem.Execute(); } } }
private void Run() { mThreadID = Thread.CurrentThread.ManagedThreadId; while (true) { bool stop = mStopEvent.WaitOne(0); if (stop) { break; } SendOrPostCallbackItem workItem = mQueueConsumer.Dequeue(); if (workItem != null) { workItem.Execute(); } } }
public SendOrPostCallbackItem Dequeue() { Console.WriteLine("Before " + mQueue.Count); mItemsInQueueEvent.WaitOne(); Console.WriteLine("After"); SendOrPostCallbackItem item = null; lock (((ICollection)mQueue).SyncRoot) { if (mQueue.Count > 0) { item = mQueue.Dequeue(); } } return(item); }
public override void Send(SendOrPostCallback d, object state) { // to avoid deadlock! if (Thread.CurrentThread.ManagedThreadId == mStaThread.ManagedThreadId) { d(state); return; } // create an item for execution SendOrPostCallbackItem item = new SendOrPostCallbackItem(d, state, ExecutionType.Send); // queue the item mQueue.Enqueue(item); // wait for the item execution to end item.ExecutionCompleteWaitHandle.WaitOne(); // if there was an exception, throw it on the caller thread, not the // sta thread. if (item.ExecutedWithException) throw item.Exception; }
public override void Send(SendOrPostCallback d, object state) { // to avoid deadlock! if (Thread.CurrentThread.ManagedThreadId == mStaThread.ManagedThreadId) { d(state); return; } // create an item for execution SendOrPostCallbackItem item = new SendOrPostCallbackItem(d, state, ExecutionType.Send); // queue the item mQueue.Enqueue(item); // wait for the item execution to end item.ExecutionCompleteWaitHandle.WaitOne(); // if there was an exception, throw it on the caller thread, not the // sta thread. if (item.ExecutedWithException) { throw item.Exception; } }