为什么Parallel.Invoke无法完成所有操作?

时间:2010-07-31 07:36:14

标签: c# c#-4.0 task-parallel-library

我在教科书中编写了一个关于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。

如果我运行程序,则只填充部分数组。 但是如果我用

替换Invoke
Task 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);

程序按预期运行(数组已完全填满)。

这可能是什么问题?

提前致谢。

1 个答案:

答案 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)
);