How can I specify an unordered Execution Block using the TPL Dataflow Library?
There is no such block in the library, but you can easily create one yourself by combining an ActionBlock
and a BufferBlock
. Something like:
public static IPropagatorBlock<TInput, TOutput>
CreateUnorderedTransformBlock<TInput, TOutput>(
Func<TInput, TOutput> func, ExecutionDataflowBlockOptions options)
{
var buffer = new BufferBlock<TOutput>(options);
var action = new ActionBlock<TInput>(
async input =>
{
var output = func(input);
await buffer.SendAsync(output);
}, options);
action.Completion.ContinueWith(
t =>
{
IDataflowBlock castedBuffer = buffer;
if (t.IsFaulted)
{
castedBuffer.Fault(t.Exception);
}
else if (t.IsCanceled)
{
// do nothing: both blocks share options,
// which means they also share CancellationToken
}
else
{
castedBuffer.Complete();
}
});
return DataflowBlock.Encapsulate(action, buffer);
}
This way, once an item is processed by the ActionBlock
, it's immediately moved to the BufferBlock
, which means ordering is not maintained.
One issue with this code is that it doesn't observe the set BoundedCapacity
well: in effect, the capacity of this block is twice the capacity set in options (because each of the two blocks has a separate capacity).