Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>To add to svick's answer, there is another benefit of bufferblocks. If you have a block with multiple output links and want to balance between them, you have to turn the output blocks to non-greedy and add a bufferblock to handle the queueing. I found the following example useful:</p> <p>Quoted from a link that is now dead:</p> <p>This is what we are planning to do:</p> <ul> <li>Some code block will post data to the BufferBlock using it’s Post(T t) method.</li> <li>This BufferBlock is linked to 3 ActionBlock instances using the LinkTo t) method of BufferBlock.</li> </ul> <p>Note, that BufferBlock does not handover copies of the input data to all the target blocks it is linked to.Instead it does so to one target block only.Here we are expecting that when one target is busy processing the request.It will be handed over to the other target.Now let’s refer to the code below:</p> <pre><code>static void Main(string[] args) { BufferBlock&lt;int&gt; bb = new BufferBlock&lt;int&gt;(); ActionBlock&lt;int&gt; a1 = new ActionBlock&lt;int&gt;((a) =&gt; { Thread.Sleep(100); Console.WriteLine("Action A1 executing with value {0}", a); } ); ActionBlock&lt;int&gt; a2 = new ActionBlock&lt;int&gt;((a) =&gt; { Thread.Sleep(50); Console.WriteLine("Action A2 executing with value {0}", a); } ); ActionBlock&lt;int&gt; a3 = new ActionBlock&lt;int&gt;((a) =&gt; { Thread.Sleep(50); Console.WriteLine("Action A3 executing with value {0}", a); } ); bb.LinkTo(a1); bb.LinkTo(a2); bb.LinkTo(a3); Task t = new Task(() =&gt; { int i = 0; while (i &lt; 10) { Thread.Sleep(50); i++; bb.Post(i); } } ); t.Start(); Console.Read(); } </code></pre> <p>When executed it produces the following output:</p> <ul> <li>Action A1 executing with value 1</li> <li>Action A1 executing with value 2</li> <li>Action A1 executing with value 3</li> <li>Action A1 executing with value 4</li> <li>Action A1 executing with value 5</li> <li>Action A1 executing with value 6</li> <li>Action A1 executing with value 7</li> <li>Action A1 executing with value 8</li> <li>Action A1 executing with value 9</li> <li>Action A1 executing with value 10</li> </ul> <p>This shows that only one target is actually executing all the data even when it’s busy(due to the Thread.Sleep(100) added purposefully).Why?</p> <p>This is because all the target blocks are by default greedy in nature and buffers the input even when they are not able to process the data.To change this behavior we have set the Greedy property to false in the DataFlowBlockOptions while initializing the ActionBlock as shown below.</p> <pre><code>static void Main(string[] args) { BufferBlock&lt;int&gt; bb = new BufferBlock&lt;int&gt;(); ActionBlock&lt;int&gt; a1 = new ActionBlock&lt;int&gt;((a) =&gt; { Thread.Sleep(100); Console.WriteLine("Action A1 executing with value {0}", a); } , new DataflowBlockOptions(taskScheduler: TaskScheduler.Default, maxDegreeOfParallelism: 1, maxMessagesPerTask: 1, cancellationToken: CancellationToken.None, //Not Greedy greedy: false) ); ActionBlock&lt;int&gt; a2 = new ActionBlock&lt;int&gt;((a) =&gt; { Thread.Sleep(50); Console.WriteLine("Action A2 executing with value {0}", a); } , new DataflowBlockOptions(taskScheduler: TaskScheduler.Default, maxDegreeOfParallelism: 1, maxMessagesPerTask: -1, cancellationToken: CancellationToken.None, greedy: false) ); ActionBlock&lt;int&gt; a3 = new ActionBlock&lt;int&gt;((a) =&gt; { Thread.Sleep(50); Console.WriteLine("Action A3 executing with value {0}", a); } , new DataflowBlockOptions(taskScheduler: TaskScheduler.Default, maxDegreeOfParallelism: 1, maxMessagesPerTask: -1, cancellationToken: CancellationToken.None, greedy: false) ); bb.LinkTo(a1); bb.LinkTo(a2); bb.LinkTo(a3); Task t = new Task(() =&gt; { int i = 0; while (i &lt; 10) { Thread.Sleep(50); i++; bb.Post(i); } } ); t.Start(); Console.Read(); } </code></pre> <p>The output of this program is:</p> <ul> <li>Action A1 executing with value 1</li> <li>Action A2 executing with value 3</li> <li>Action A1 executing with value 2</li> <li>Action A3 executing with value 6</li> <li>Action A3 executing with value 7</li> <li>Action A3 executing with value 8</li> <li>Action A2 executing with value 5</li> <li>Action A3 executing with value 9</li> <li>Action A1 executing with value 4</li> <li>Action A2 executing with value 10</li> </ul> <p>This clearly a distribution of the data across three ActionBlock(s) as expected.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload