Hashed / Blocked ActionBlocks

I have a constant stream of some elements that I need to process in parallel, so I use TPL Dataflow . The trick is that elements that have the same key (similar to a dictionary) must be processed in FIFO order and not be parallel to each other (they can be parallel to other elements with different values).

The work in progress is very processor-bound with minimal asynchronous locks, so my solution was to create an ActionBlock<T> array of size Environment.ProcessorCount without parallelism and publish according to the GetHashCode key value.

Creature:

 _actionBlocks = new ActionBlock<Item>[Environment.ProcessorCount]; for (int i = 0; i < _actionBlocks.Length; i++) { _actionBlocks[i] = new ActionBlock<Item>(_ => ProcessItemAsync(_)); } 

Using:

 bool ProcessItem(Key key, Item item) { var actionBlock = _actionBlocks[(uint)key.GetHashCode() % _actionBlocks.Length]; return actionBlock.Post(item); } 

So my question is: is this the best solution to my problem? Am I hurt performance / scalability? Did I miss something?

+6
source share
1 answer

I think your approach is reasonable if you know that the hash codes will be well distributed.

If you want better protection against bad allocations, you can use more ActionBlock by limiting their overall concurrency level using one custom TaskScheduler shared by all blocks. You can find such a scheduler in ParallelExtensionsExtras or on MSDN .

+3
source

All Articles