As already been said in linked question, big number of threads doesn't guarantee the performance, as if their number gets more than the number of logical cores, you got a thread starvation situation with no real work being done.
However, if you still need to handle the number of a concurrent operations, you may give a try to the TPL Dataflow
library, with settings up the MaxDegreeOfParallelism
, like in this tutorial.
var workerBlock = new ActionBlock<EventArgs>(
// Process event
e => Process(e),
// Specify a maximum degree of parallelism.
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = InitialCount
});
var bufferBlock = new BufferBlock();
// link the blocks for automatically propagading the messages
bufferBlock.LinkTo(workerBlock);
// asynchronously send the message
await bufferBlock.SendAsync(...);
// synchronously send the message
bufferBlock.Post(...);
BufferBlock
is a queue, so the order of messages will be preserved. Also, you can add the different handlers (with a different degree of parallelism) with linking the blocks with filter lambda:
bufferBlock.LinkTo(cpuWorkerBlock, e => e is CpuEventArgs);
bufferBlock.LinkTo(networkWorkerBlock, e => e is NetworkEventArgs);
bufferBlock.LinkTo(diskWorkerBlock, e => e is DiskEventArgs);
but in this case you should setup a default handler at the end of the chain, so the message wouldn't disappear (you may use a NullTarget
block for this):
bufferBlock.LinkTo(DataflowBlock.NullTarget<EventArgs>);
Also, the block could be an observers, so they perfectly work with Reactive Extensions on UI side.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…