async Task Worker() { for (; ; ) { WorkHandle work; lock (_lock) { if (_workQueue.Count < 1) return; work = _workQueue.Dequeue(); } #if DEBUG _work = work; #endif try { work.TryDeregister(); await work.RunAsync().ConfigureAwait(false); } catch (Exception ex) { Debug.WriteLine("AsyncFifoWorker.Worker() failed: " + ex.ExtendedMessage()); } #if DEBUG _work = null; #endif work.Dispose(); } }
WorkHandle PostWork(Func<Task> workFunc, bool createTcs, string description, CancellationToken cancellationToken) { if (workFunc == null) throw new ArgumentNullException(nameof(workFunc)); cancellationToken.ThrowIfCancellationRequested(); WorkHandle work; lock (_lock) { if (_isClosed) throw new InvalidOperationException("AsyncFifoWorker is closed"); work = new WorkHandle(workFunc, createTcs ? new TaskCompletionSource<object>() : null); #if DEBUG work.Description = description; #endif _workQueue.Enqueue(work); } if (!work.Register(RemoveWork, cancellationToken)) { Debug.WriteLine("AsyncFifoWorker.PostWork() work already done"); return work; } try { _signalTask.Fire(); } catch (ObjectDisposedException) { RemoveWork(work); if (_workQueue.Count > 0) Debug.WriteLine("AsyncFifoWorker.Post() object disposed but there are still {0} pending", _workQueue.Count); throw; } return work; }