我在教科书中编写了一个关于C#中并行编程的例子。本书建议Parallel.Invoke可以替换任务的创建,调用和等待。但是,我尝试并发现如果我使用Parallel.Invoke,则在返回值之前任务将无法完成。但理论上,Parallel.Invoke应该总是等待。
代码:
private byte[] getDataForGraph(int dataSize)
{
byte[] data = new byte[dataSize];
Parallel.Invoke(
() => Task.Factory.StartNew(() => generateGraphData(data, 0, pixelWidth / 8)),
() => Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 8,
pixelWidth / 4)),
() => Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 4,
pixelWidth * 3 / 8)),
() => Task.Factory.StartNew(() => generateGraphData(data, pixelWidth * 3 / 8,
pixelWidth / 2)));
return data;
}
执行该功能的方法:
Task<byte[]> getDataTask = Task<byte[]>.Factory.StartNew(() => getDataForGraph(dataSize));
byte[] data = getDataTask.Result;
private void generateGraphData(byte[] data, int partitionStart, int partitionEnd)
是一个填充数据数组的函数,从partitionStart到partitionEnd。
如果我运行程序,则只填充部分数组。 但是如果我用
替换InvokeTask first = Task.Factory.StartNew(() => generateGraphData(data, 0, pixelWidth / 8));
Task second = Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 8, pixelWidth / 4));
Task third = Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 4, pixelWidth * 3 / 8));
Task fourth = Task.Factory.StartNew(() => generateGraphData(data, pixelWidth * 3 / 8, pixelWidth / 2));
Task.WaitAll(first, second, third, fourth);
程序按预期运行(数组已完全填满)。
这可能是什么问题?
提前致谢。
答案 0 :(得分:5)
执行操作直到完成。在您的情况下,每个操作都是调用Task.Factory.StartNew(...)
- 并 已完成;但是,无法保证每个任务都已排队/处理过。区别在于WaitAll
(您未在Parallel
示例中调用过)。
这里的一个选择是将其减少为:
Parallel.Invoke(
() => generateGraphData(data, 0, pixelWidth / 8),
() => generateGraphData(data, pixelWidth / 8, pixelWidth / 4),
() => generateGraphData(data, pixelWidth / 4, pixelWidth * 3 / 8),
() => generateGraphData(data, pixelWidth * 3 / 8, pixelWidth / 2)
);