散列/分片ActionBlocks

i3a*_*non 6 .net c# task-parallel-library async-await tpl-dataflow

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

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

创建:

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

用法:

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

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

svi*_*ick 3

我认为你的方法是合理的,假设你知道哈希码会很好地分布。

如果您想更好地防止不良分布,您可以使用更多数量的ActionBlocks,同时通过使用所有块共享的单个自定义来限制它们的总并发级别TaskScheduler。您可以在 ParallelExtensionsExtrasMSDN中找到此类调度程序。