【发布时间】:2016-11-17 03:26:43
【问题描述】:
我需要并行启动任务,但我选择使用Task.Run 而不是Parallel.Foreach,这样我可以在所有任务完成后获得一些反馈并启用 UI 控件。
private async void buttonStart_Click(object sender, EventArgs e)
{
var cells = objectListView.CheckedObjects;
if(cells != null)
{
List<Task> tasks = new List<Task>();
foreach (Cell c in cells)
{
Cell cell = c;
var progressHandler = new Progress<string>(value =>
{
cell.Status = value;
});
var progress = progressHandler as IProgress<string>;
Task t = Task.Run(() =>
{
progress.Report("Starting...");
int a = 123;
for (int i = 0; i < 200000; i++)
{
a = a + i;
Task.Delay(500).Wait();
}
progress.Report("Done");
});
tasks.Add(t);
}
await Task.WhenAll(tasks);
Console.WriteLine("Done, enabld UI controls");
}
}
所以我期望在 UI 中几乎立即看到所有项目的“正在启动...”。我实际看到的是前 4 个项目是“正在启动...”(我猜是因为每个线程都使用了所有 4 个 CPU 内核),然后每秒或更少的新项目是“启动”。我总共有 37 个项目,所有项目启动所有任务大约需要 30 秒。
我怎样才能让它尽可能平行?
【问题讨论】:
-
使用一个并行的 foreach,因为你一次开始一个..
-
当您看到应用程序这样运行时,您是如何运行的?你有 VS 附加吗?
-
答案是你不能。你不能让它比你拥有的内核更多地并行。虽然你可以产生多个线程
-
@SriramSakthivel 他说他有 4 个内核并想要 4 个线程?
-
@Liam 他的任务不会很快完成。因此 ThreadPool 将使用其启发式添加线程。需要花时间。看起来他的 4 个内核正在被使用,但他通过进入睡眠状态来浪费线程。
标签: c# parallel-processing async-await task-parallel-library