1

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

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

这里可能有什么问题?

提前致谢。

4

1 回答 1

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)
);
于 2010-07-31T07:39:18.997 回答