Search code examples
c#.nettask-parallel-librarytpl-dataflow

Post Array to BatchBlock


I am trying Push some data to a BatchBlock and I need to pass it one by one in foreach loop. I tried to search some method to pass an array to batchBlock but I didn't find any method like it.

Is there any method or work around to accept array, if not what is the reason to not include this functionality.

var modelsDataTable = modelsAndFormulasDataSet.Tables[0];

foreach (DataRow row in modelsDataTable.Rows)
{
modelIdsBatchBlock.Target1.Post<long>(row.Field<long>(AppConstants.ModelsDataTable.ModelId.ToString()));
}

Solution

  • Thank you for clarifying the question. Based on this desired behavior:

    one situation which I have is like, var transformBlock = new TransformBlock<int, List<long>>, TransformBlock returns List<long> and I linked it to BatchBlock transformBlock.LinkTo(batchBlock) and batchBlock should process values when batchsized reached to 3 values not 15 values.

    What you're looking for is a TransformManyBlock. Here's an example the simulates your desired behavior in an NUnit test:

    [TestFixture]
    public class BlockTester
    {
        [Test]
        public async Task BuildPipeline()
        {
            var inputBlock = new TransformBlock<int, List<long>>(x => Enumerable.Repeat((long)0, 6).ToList());
            var xFormBlock = new TransformManyBlock<List<long>, long>(x => x);
            var batchBlock = new BatchBlock<long>(3);
            var testBlock = new ActionBlock<long[]>(x => Assert.AreEqual(3, x.Length));
    
            inputBlock.LinkTo(xFormBlock, new DataflowLinkOptions() { PropagateCompletion = true });
            xFormBlock.LinkTo(batchBlock, new DataflowLinkOptions() { PropagateCompletion = true });
            batchBlock.LinkTo(testBlock, new DataflowLinkOptions() { PropagateCompletion = true });
    
            await inputBlock.SendAsync(1);
            await inputBlock.SendAsync(2);
            await inputBlock.SendAsync(3);
    
            inputBlock.Complete();
            await testBlock.Completion;
        }
    }