title: Why does BufferBlock<T>.ReceiveAsync() hang when data is available?
body: <p>I am new to TPL Dataflow. </p>
  
  <p>I am trying to build a throttled async update to a fairly fast flowing input stream. BufferBlock seemed a nice match for this with the idea that I could call the ReceiveAll() to grab everything off the buffer and on the occasions there is nothing there I can await on a ReceiveAsync() to pick up the next element as it arrives.</p>
  
  <p>But it seems to sometimes hang on the ReceiveAsync() call; and the conditions of failure are odd.</p>
  
  <p><strong>Please note</strong> I am interested in why this hangs. I have already found another way to make the application I am working on work, but it is possibly not as neat or extensible as I am not using TPL Dataflow since I obviously don't understand how it works.</p>
  
  <p><strong>Further note</strong> The key usage here is that I do a <em>TryReceiveAll()</em> then <em>await ReceiveAsync()</em> if that fails. This is a common pattern where burst data arrives and I want to process data so far as a batch. Which is the reason that I don't want to just loop on the <em>ReceiveAsync()</em>, and thus why just directly hooking an <em>ActionBlock</em> or a <em>TransformBlock</em> would not work. If I remove the <em>TryReceiveAll()</em> my version seems to work as expected; though, as other comments have noted the behaviour, seems to be different for different people so this may be a coincidence.</p>
  
  <p>Here is a failing example... drop it in a console app with <em>System.Threading.Tasks.Dataflow.dll</em> referenced and usings:</p>
  
  <pre><code>using System.Threading;
  using System.Threading.Tasks;
  using System.Threading.Tasks.Dataflow;
  </code></pre>
  
  <p>Failing example:</p>
  
  <pre><code>class Program
  {
      static void Main(string[] args)
      {
          var context = new CancellationTokenSource();
          var buffer = new BufferBlock&lt;int&gt;(new DataflowBlockOptions { CancellationToken = context.Token });
          var task = Task.Run(() =&gt;ProcessBuffer(buffer, context.Token), context.Token);
  
          // shove 10 things onto the buffer
          for(int i = 0; i &lt; 10; i++)
          {
              // shove something on the buffer every second
              buffer.Post(i);
              Thread.Sleep(1000);
          }
          context.Cancel();
      }
  
      // 1. We expect to see something hit the buffer and go immediately through on the TryReceiveAll
      // 2. Then we should see nothing for a second
      // 3. Then we immediately process the next element from the await ReceiveAsync.
      // 4. We should then repeat 2 &amp; 3 'till i == 10 as there will be nothign for TryReceiveAll.
      static async Task ProcessBuffer(BufferBlock&lt;int&gt; buffer, CancellationToken token)
      {
          try
          {
              while (!token.IsCancellationRequested)
              {
                  Console.WriteLine(DateTime.Now.ToShortTimeString() + ": This Breaks it...");
                  IList&lt;int&gt; elements;
                  if (!buffer.TryReceiveAll(out elements))
                  {
                      try
                      {
                          var element = await buffer.ReceiveAsync(TimeSpan.FromMilliseconds(5000), token);
                          elements = new List&lt;int&gt; { element };
                      }
                      catch (TimeoutException) { Console.WriteLine("Failed to get anything on await..."); }
                  }
                  if (elements != null) Console.WriteLine("Elements: " + string.Join(", ", elements));
              }
          }
          catch (Exception e) { Console.WriteLine("Exception in thread: " + e.ToString()); }
      }
  }
  </code></pre>
  
  <p>output is:</p>
  
  <pre><code>11:27: This Breaks it...
  Elements: 0
  11:27: This Breaks it...
  Failed to get anything on await...
  11:27: This Breaks it...
  Elements: 1, 2, 3, 4, 5
  </code></pre>
  
  <p>...And so on</p>
  
  <p>But if I change the log line</p>
  
  <pre><code>Console.WriteLine(DateTime.Now.ToShortTimeString() + ": This Breaks it...");
  </code></pre>
  
  <p>to</p>
  
  <pre><code>Console.WriteLine("This Works...");
  </code></pre>
  
  <p>The the output comes out as expected:</p>
  
  <pre><code>This Works...
  Elements: 0
  This Works...
  Elements: 1
  This Works...
  Elements: 2
  This Works...
  </code></pre>
  
  <p>etc.
  But even the act of copying text from the console will switch it back to the failing output.</p>
  
  <p>Ideas?</p>