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

正在完成的工作非常受 CPU 限制,并且具有最少的异步锁,因此我的解决方案是创建一个数组 ActionBlock<T>的大小为 Environment.ProcessorCount 没有并行性并根据密钥发布给他们 GetHashCode 价值。

创建:

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

用法:

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

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

有帮助吗?

解决方案

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

如果您想更好地防止不良发行版,您可以使用更多数量的 ActionBlock同时通过使用单个自定义限制其总并发级别 TaskScheduler 由所有块共享。你可以找到这样的调度程序 并行扩展额外 或者 在 MSDN 上.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top