internal void Add(Task task, WhiteBox whiteBox) { if (null == task) { throw new ArgumentNullException("task"); } // whitebox testing results-- we initialize pipeSz with an inconsistent copy of Count because it's better than nothing and will reflect that the pipeline size was in a valid state during some portion of this method, even if it isn't at a properly synchronized moment. int pipeSz = Count; var full = false; // we should be using a try...finally to execute the whitebox testing logic here but it apparently adds too much latency to be palatable for AsyncPipelineSimpleTest(), which is sensitive to latency. try { TaskCompletionSource <bool> tcs; lock (lockable) { if (!IsFull && waiting.Count == 0) { task.ContinueWith(OnTaskCompletion).Ignore(); running.Add(task); pipeSz = Count; return; } full = true; tcs = new TaskCompletionSource <bool>(); waiting.AddLast(Tuple.Create(task, tcs)); } tcs.Task.Wait(); // the following quantity is an inconsistent value but i don't have a means to geuuuut one in this part of the // code because adding the actual add has already been performed from within a continuation. pipeSz = Count; } finally { if (whiteBox != null) { whiteBox.Reset(); whiteBox.PipelineSize = pipeSz; whiteBox.PipelineFull = full; } } }
internal void Wait(WhiteBox whiteBox) { var tasks = new List <Task>(); lock (lockable) { tasks.AddRange(running); foreach (var i in waiting) { tasks.Add(i.Item2.Task); } } Task.WhenAll(tasks).Wait(); if (null != whiteBox) { whiteBox.Reset(); whiteBox.PipelineSize = 0; } }