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

LLS*_*LLS 1 c# task-parallel-library c#-4.0

我在教科书中编写了一个关于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;
    }
Run Code Online (Sandbox Code Playgroud)

以及执行该功能的方式:

Task<byte[]> getDataTask = Task<byte[]>.Factory.StartNew(() => getDataForGraph(dataSize));
byte[] data = getDataTask.Result;
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

程序按预期运行(数组已完全填充).

这可能是什么问题?

提前致谢.

Mar*_*ell 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)
);
Run Code Online (Sandbox Code Playgroud)