void QueueAction(T next) { var ct = CancelTokenSrc.Token; Task task = new Task(() => { // If we are cancelled before we start, push the job back on the queue so it can be dealt with by another runner. if (ct.IsCancellationRequested) { Queue.Enqueue(next); return; } SafeAction(next); }, ct); task.ContinueWith((t) => { byte val; RunningTasks.TryRemove(t, out val); WaitForTaskEvent.Set( ); }, ct); RunningTasks.TryAdd(task, 0); task.Start( ); }