private AsyncFifoWorker.WorkHandle PostWork(Func <Task> workFunc, bool createTcs, string description, CancellationToken cancellationToken) { if (workFunc == null) { throw new ArgumentNullException("workFunc"); } cancellationToken.ThrowIfCancellationRequested(); bool lockTaken = false; object obj = null; AsyncFifoWorker.WorkHandle workHandle; try { Monitor.Enter(obj = this._lock, ref lockTaken); if (this._isClosed) { throw new InvalidOperationException("AsyncFifoWorker is closed"); } workHandle = new AsyncFifoWorker.WorkHandle(workFunc, createTcs ? new TaskCompletionSource <object>() : (TaskCompletionSource <object>)null); workHandle.Description = description; this._workQueue.Enqueue(workHandle); } finally { if (lockTaken) { Monitor.Exit(obj); } } if (!workHandle.Register(new Action <AsyncFifoWorker.WorkHandle>(this.RemoveWork), cancellationToken)) { Debug.WriteLine("AsyncFifoWorker.PostWork() work already done"); return(workHandle); } try { this._signalTask.Fire(); } catch (ObjectDisposedException ex) { this.RemoveWork((object)workHandle); if (this._workQueue.Count > 0) { Debug.WriteLine("AsyncFifoWorker.Post() object disposed but there are still {0} pending", (object)this._workQueue.Count); } throw; } return(workHandle); }
private async Task Worker() { while (true) { bool lockTaken = false; AsyncFifoWorker.WorkHandle work; object obj = null; try { Monitor.Enter(obj = this._lock, ref lockTaken); if (this._workQueue.Count >= 1) { work = this._workQueue.Dequeue(); } else { break; } } finally { if (lockTaken) { Monitor.Exit(obj); } } this._work = work; try { work.TryDeregister(); await work.RunAsync().ConfigureAwait(false); } catch (Exception ex) { Debug.WriteLine("AsyncFifoWorker.Worker() failed: " + ExceptionExtensions.ExtendedMessage(ex)); } this._work = (AsyncFifoWorker.WorkHandle)null; work.Dispose(); } }
private void RemoveWork(object workObject) { AsyncFifoWorker.WorkHandle workHandle = (AsyncFifoWorker.WorkHandle)workObject; bool lockTaken = false; object obj = null; try { Monitor.Enter(obj = this._lock, ref lockTaken); if (!QueueExtensions.Remove <AsyncFifoWorker.WorkHandle>(this._workQueue, workHandle)) { return; } } finally { if (lockTaken) { Monitor.Exit(obj); } } workHandle.Dispose(); }