我有一个List<byte[]>
,我喜欢将每个byte[]
反序列化为Foo。列表是有序的,我喜欢编写一个并行循环,其中生成的List<Foo>
包含与原始byte[]
相同顺序的所有Foo。该列表非常大,可以使并行操作变得有价值。有没有内置的方法来实现这一目标?
如果没有,任何想法如何实现同步运行的加速?
由于
答案 0 :(得分:8)
根据您提供的信息,我知道您希望有一个Foo的输出数组,其大小等于输入的字节数组?它是否正确?
如果是这样,是的,操作很简单。不要理会锁定或同步构造,这些会侵蚀并行化带给您的所有速度。
相反,如果遵守这个简单的规则,任何算法都可以并行化,而无需锁定或同步:
对于处理的每个输入元素X [i],您可以从任何输入元素X [j]读取,但只能写入输出元素Y [i]
查找Scatter / Gather,这种类型的操作称为聚集,因为只写入一个输出元素。
如果你可以使用上面的原则,那么你想要在前面创建你的输出数组Foo [],并在输入数组上使用Parallel.For not ForEach。
E.g。
List<byte[]> inputArray = new List<byte[]>();
int[] outputArray = new int[inputArray.Count];
var waitHandle = new ManualResetEvent(false);
int counter = 0;
Parallel.For(0, inputArray.Count, index =>
{
// Pass index to for loop, do long running operation
// on input items
// writing to only a single output item
outputArray[index] = DoOperation(inputArray[index]);
if(Interlocked.Increment(ref counter) == inputArray.Count -1)
{
waitHandle.Set();
}
});
waitHandler.WaitOne();
// Optional conversion back to list if you wanted this
var outputList = outputArray.ToList();
答案 1 :(得分:2)
您可以使用带有索引int键的线程安全字典来存储来自foo的结果 所以最后你将拥有字典中的所有数据订阅者