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)
程序按预期运行(数组已完全填充).
这可能是什么问题?
提前致谢.
它执行操作直到完成.在你的情况,每个动作都调用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)