【发布时间】:2014-01-27 09:38:50
【问题描述】:
我需要并行处理某些项目,因此我使用的是TPL Dataflow。问题是共享相同键的项目(类似于字典)应该以先进先出的顺序处理,而不是彼此并行(它们可以与具有不同值的其他项目并行)。
正在完成的工作非常受 CPU 限制,并且异步锁最少,因此我的解决方案是创建一个大小为 Environment.ProcessorCount 的 ActionBlock<T>s 数组,没有并行性,并根据密钥的 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);
}
所以,我的问题是,这是解决我问题的最佳方法吗?我会损害性能/可扩展性吗?我错过了什么吗?
【问题讨论】:
-
我喜欢它。我想不出另一种不需要存储的方法。我认为只要你确保你的哈希码被正确分配,这应该没问题。
-
依赖
GetHashCode的值对我来说听起来很奇怪,你为什么会有它?实际的需求是“相等的物品应该按照先进先出的顺序处理”吗? -
@svick 更像是 具有相同键的项目应按 FIFO 顺序处理,类似于使用字典的方式(实际上不必是相同的项目类型)。我将更新问题以使其更清楚。
-
@I3arnon 你怎么知道所有线程至少有相当数量的工作要做?
(uint)key.GetHashCode() % _actionBlocks.Length有可能分布不均,某些内核不会做任何事情。 -
@MarcinJuraszek 这是真的。我已经确保哈希值尽可能均匀,并且通过测试我发现确实如此。但是……这是我把它放在这里的原因之一。
标签: c# .net task-parallel-library async-await tpl-dataflow