title: Wait for all items to be transformed via TransformBlock
body: <p>I'm looking for a way to <code>await</code> all items to be processed via TPL <code>TransformBlock</code>.
  Sample code:</p>
  
  <pre><code>var transformBlock = new TransformBlock&lt;int, int&gt;(async number =&gt;
  {
      await Task.Delay(TimeSpan.FromMilliseconds(300));
      return number * 2;
  }, new ExecutionDataflowBlockOptions
  {
      MaxDegreeOfParallelism = Environment.ProcessorCount
  });
  
  foreach (var number in Enumerable.Range(1, 100))
  {
      transformBlock.Post(number);
  }
  
  transformBlock.Complete();
  </code></pre>
  
  <p>At this point I have a call to <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.dataflow.transformblock-2.complete?view=netcore-2.2&amp;viewFallbackFrom=netframework-4.7#System_Threading_Tasks_Dataflow_TransformBlock_2_Complete" rel="nofollow noreferrer">Complete</a>, which to my understanding signals to <code>TransformBlock</code> to not receive any more items &amp; to finish processing all available data (available in <code>InputQueue</code>).</p>
  
  <p>But I'm not sure how to <code>await</code> for all items to be available ?</p>
  
  <p><a href="https://stackoverflow.com/a/27188065/997668">Awaiting Completion task </a> is not a solution becase as the answer states:</p>
  
  <blockquote>
    <p>An instance of TransformBlock is not considered "complete" until the
    following conditions are met:</p>
    
    <ol>
    <li>TransformBlock.Complete() has been called</li>
    <li>InputCount == 0 – the block has applied its transformation to every incoming element</li>
    <li>OutputCount == 0 – all transformed elements have left the output buffer</li>
    </ol>
  </blockquote>
  
  <p>One way I found is to <code>await</code> all tasks returned from <code>ReceiveAsync</code>, e.g.</p>
  
  <pre><code>var tasks = new List&lt;Task&lt;int&gt;&gt;();
  foreach (var number in Enumerable.Range(1, 100))
  {
      transformBlock.Post(number);
  
      tasks.Add(transformBlock.ReceiveAsync());
  }
  
  transformBlock.Complete();
  
  await Task.WhenAll(tasks);
  
  tasks.Select(t =&gt; t.GetAwaiter().GetResult())
       .ToList()
       .ForEach(Console.WriteLine);
  </code></pre>
  
  <p>However, I'm not really sure this is 100 % correct.</p>
  
  <p>Another options I see in <a href="https://stackoverflow.com/a/27188065/997668">this answer</a> suggestion made to add another TPL blocks and propogate completion, that way we can await transform block's completion and then consume results from linked TPL block, but it does seem like overcomplication of the task &amp; I'm assuming there is <em>better</em> (built-in or less verbose) way ?</p>