散列/分片ActionBlocks

我需要并行处理某些项目,因此我使用的是TPL Dataflow 。 问题在于,共享相同密钥(类似于字典)的项目应按FIFO顺序处理,而不是彼此平行(它们可以与具有不同值的其他项目并行)。

正在完成的工作是CPU绑定最小的异步锁,所以我的解决方案是创建一个ActionBlock的数组,其大小为Environment.ProcessorCount ,没有并行性,并根据密钥的GetHashCode值发布到它们。

创建:

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

用法:

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

所以,我的问题是,这是我问题的最佳解决方案吗? 我是否会损害性能/可扩展性? 我错过了什么吗?

我认为您的方法是合理的,假设您知道哈希码将很好地分发。

如果您希望更好地防止错误分发,可以使用大量ActionBlock ,同时通过使用所有块共享的单个自定义TaskScheduler来限制其总并发级别。 您可以在ParallelExtensionsExtras或MSDN上找到此类调度程序。