Search code examples
c#concurrencytask-parallel-library.net-4.5tpl-dataflow

Can an ActionBlock link to another ActionBlock with more parameters in it?


I am still getting a hang of TPL DataFlow so bear with me.

My application requires that queue is executed upon in parallel while retaining its order. This led me to the DataFlow library and what I am trying to do. I am wondering if there is a way to link one ActionBlock to another and the second taking a value from the first to operate on.
Pseudo-example:

var block1 = new ActionBlock<ByteBuffer>(buffer => {
   // code generating a hash of the byte buffer to pass to next block 
    ulong hash = generateHash(buffer);
   // this is what i would like to pass to the next ActionBlock
    var tup = Tuple<ByteBuffer, ulong>(buffer, along);
}, dataFlowOpts);
var block2 = new ActionBlock<Tuple<ByteBuffer, ulong>(tup => {
    /* code to act on the buffer and hash */
}, dataFlowOpts);

block1.LinkTo(block2); // Is there something like this that would use the correct params?

Is what I'm trying to do possible? Does this even make sense? The reason I have these separated into two ActionBlocks is I would like to reuse block2 in another codepath (hashing the contents of a different ByteBuffer differently.)

Maybe there is a better way? Really, I am just trying to hash objects as they come in in a concurrent fashion while retaining FIFO order as it's way too slow to hash these synchronously.


Solution

  • Just use the TransformBlock:

    var block1 = new TransformBlock<ByteBuffer, Tuple<ByteBuffer, ulong>>(buffer => {
        // code generating a hash of the byte buffer to pass to next block 
        ulong hash = generateHash(buffer);
        // this is what i would like to pass to the next ActionBlock
        return Tuple<ByteBuffer, ulong>(buffer, along);
    }, dataFlowOpts);
    var block2 = new ActionBlock<Tuple<ByteBuffer, ulong>(tup => {
        /* code to act on the buffer and hash */
    }, dataFlowOpts);
    
    block1.LinkTo(block2); // Is there something like this that would use the correct params?
    

    Or, probably better option to use a DTO class with two properties: buffer and hash, as Tuple isn't much readable. Also, consider a new C# feature about named tuples.