title: Linking dynamically created ActionBlocks to a BufferBlock
body: <p>I'm not sure if this is possible, but if it is, I'm probably not doing it right. Let's suppose I have one shared buffer that is linked to many consumers (ActionBlocks). Each consumer should consume data that satisfies a predicate used to link it to the buffer. For example, ActionBlock1 should consume numbers that satisfy <code>x =&gt; x % 5 == 0</code>, ActionBlock2 should consume only <code>x =&gt; x % 5 == 1</code> etc.</p>
  
  <p>Here's what I've got: </p>
  
  <pre><code>private static ITargetBlock&lt;int&gt; BuildPipeline(int NumProductionLines)
  {
      var productionQueue = new BufferBlock&lt;int&gt;();
  
      for (int i = 0; i &lt; NumProductionLines; i++)
      {
          ActionBlock&lt;int&gt; productionLine = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", i + 1, num));
  
          productionQueue.LinkTo(productionLine, x =&gt; x % NumProductionLines == i);
      }
  
      return productionQueue;
  }
  </code></pre>
  
  <p>And then I call:</p>
  
  <pre><code>Random rnd = new Random();
  
  ITargetBlock&lt;int&gt; temp = BuildPipeline(5);
  
  while (true)
  {
      temp.Post(rnd.Next(255));
  }
  </code></pre>
  
  <p>However this does not work. No output is displayed in the console. If i modify <code>BuildPipeline</code> method as:</p>
  
  <pre><code>private static ITargetBlock&lt;int&gt; BuildPipeline(int NumProductionLines)
  {
      var productionQueue = new BufferBlock&lt;int&gt;();
  
      ActionBlock&lt;int&gt; productionLine1 = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", 1, num));
      ActionBlock&lt;int&gt; productionLine2 = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", 2, num));
      ActionBlock&lt;int&gt; productionLine3 = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", 3, num));
      ActionBlock&lt;int&gt; productionLine4 = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", 4, num));
      ActionBlock&lt;int&gt; productionLine5 = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", 5, num));
  
      productionQueue.LinkTo(productionLine1, x =&gt; x % 5 == 0);
      productionQueue.LinkTo(productionLine2, x =&gt; x % 5 == 1);
      productionQueue.LinkTo(productionLine3, x =&gt; x % 5 == 2);
      productionQueue.LinkTo(productionLine4, x =&gt; x % 5 == 3);
      productionQueue.LinkTo(productionLine5, x =&gt; x % 5 == 4);
  
      return productionQueue;
  }
  </code></pre>
  
  <p>the code does what it's expected to do.</p>
  
  <p>Can someone shed light on why dynamically creating and linking action blocks doesn't work?</p>
  
  <p>P.S. If I break into code right after <code>ITargetBlock&lt;int&gt; temp = BuildPipeline(5);</code> temp does show that 5 targets are linked to the buffer. And Id of each target is different.</p>
  
  <p>Thanks in advance</p>
  
  <p>EDIT: Added changes suggested by svick but still no good:</p>
  
  <pre><code>private static ITargetBlock&lt;int&gt; BuildPipeline(int NumProductionLines)
  {
      var productionQueue = new BufferBlock&lt;int&gt;();
      var opt = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 };
  
      for (int i = 0; i &lt; NumProductionLines; i++)
      {
          ActionBlock&lt;int&gt; productionLine = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", i + 1, num));
  
          int j = i;
          productionQueue.LinkTo(productionLine, x =&gt; x % NumProductionLines == j);
      }
  
      ActionBlock&lt;int&gt; discardedLine = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Discarded: {0}", num));
      productionQueue.LinkTo(discardedLine);
  
      return productionQueue;
  }
  </code></pre>
  
  <p>Now only second production line processes data (the one satisfying x % 5 == 1 predicate). And the data does not satisfy the predicate, meaning I get numbers ending in 9 and 7.</p>
  
  <p>EDIT: Working code would look something like the following:</p>
  
  <pre><code>private static ITargetBlock&lt;int&gt; BuildPipeline(int NumProductionLines)
  {
      var productionQueue = new BufferBlock&lt;int&gt;();
      var opt = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 };
  
      for (int i = 0; i &lt; NumProductionLines; i++)
      {
          int j = i;
          ActionBlock&lt;int&gt; productionLine = new ActionBlock&lt;int&gt;(num =&gt; Console.WriteLine("Processed by line {0}: {1}", j + 1, num));
  
          productionQueue.LinkTo(productionLine, x =&gt; x % NumProductionLines == j);
      }
  
      productionQueue.LinkTo(DataflowBlock.NullTarget&lt;int&gt;());
  
      return productionQueue;
  }
  </code></pre>