Dotnet-api-docs: Effect of setting MaxMessagesPerTask is not clear

Created on 12 Jan 2019  Â·  3Comments  Â·  Source: dotnet/dotnet-api-docs

I wrote some small tests but I can not see any effect on the outcome.
?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Not Triaged Pri2 area-System.Threading.Tasks dotnet-approd

Most helpful comment

It's most visible if you also use a task scheduler with limited degree of parallelism. For example, consider this code:

```c#
var exclusiveScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler;

var options = new ExecutionDataflowBlockOptions
{
TaskScheduler = exclusiveScheduler,
MaxMessagesPerTask = 1
};

var blockA = new ActionBlock(i => Console.WriteLine($"A {i}"), options);
var blockB = new ActionBlock(i => Console.WriteLine($"B {i}"), options);

for (int i = 0; i < 5; i++)
{
blockA.Post(i);
blockB.Post(i);
}

blockA.Complete();
blockB.Complete();

Task.WaitAll(blockA.Completion, blockB.Completion);

If you run it, you'll see that processing of the two blocks is interleaved, because each `Task` scheduled to the task scheduler will process only one message:

A 0
B 0
A 1
B 1
A 2
B 2
A 3
B 3
A 4
B 4

But if you set `MaxMessagesPerTask` to -1 (the default), one block will process all its messages first, before the second one has any chance to run:

A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
```

I believe this property is most useful when tweaking performance: more messages per task leads to better throughput, while less messages per task can lead to better latency.

I think the documentation should be expanded here, but I'm not sure a full example (like the one I just showed) is necessary.

All 3 comments

It's most visible if you also use a task scheduler with limited degree of parallelism. For example, consider this code:

```c#
var exclusiveScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler;

var options = new ExecutionDataflowBlockOptions
{
TaskScheduler = exclusiveScheduler,
MaxMessagesPerTask = 1
};

var blockA = new ActionBlock(i => Console.WriteLine($"A {i}"), options);
var blockB = new ActionBlock(i => Console.WriteLine($"B {i}"), options);

for (int i = 0; i < 5; i++)
{
blockA.Post(i);
blockB.Post(i);
}

blockA.Complete();
blockB.Complete();

Task.WaitAll(blockA.Completion, blockB.Completion);

If you run it, you'll see that processing of the two blocks is interleaved, because each `Task` scheduled to the task scheduler will process only one message:

A 0
B 0
A 1
B 1
A 2
B 2
A 3
B 3
A 4
B 4

But if you set `MaxMessagesPerTask` to -1 (the default), one block will process all its messages first, before the second one has any chance to run:

A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
```

I believe this property is most useful when tweaking performance: more messages per task leads to better throughput, while less messages per task can lead to better latency.

I think the documentation should be expanded here, but I'm not sure a full example (like the one I just showed) is necessary.

I think the documentation should be expanded here, but I'm not sure a full example (like the one I just showed) is necessary.

Your example was helpful, and given the very sparse documentation, I think it would be worthwhile for you to send a PR with your example as an addition.

Was this page helpful?
0 / 5 - 0 ratings