我有一个foreach()
循环播放15个报告,并为每个报告生成一个PDF。 PDF生成过程很慢(每个3秒)。但是如果我可以与线程同时生成它们,那么所有15个都可以在4-5秒内完成。一个限制是在生成所有pdf之前,函数不能返回。另外,15个并发工作线程是否会导致dotnet / windows出现问题或不稳定?
这是我的伪代码:
private void makePDFs(string path) {
string[] folders = Directory.GetDirectories(path);
foreach(string folderPath in folders) {
generatePDF(...);
}
// DO NOT RETURN UNTIL ALL PDFs HAVE BEEN GENERATED
}
}
实现这一目标的最简单方法是什么?
答案 0 :(得分:4)
最直接的方法是使用Parallel.ForEach:
private void makePDFs(string path)
{
string[] folders = Directory.GetDirectories(path);
Parallel.ForEach(folders, (folderPath) =>
{
generatePDF(folderPath);
};
//WILL NOT RETURN UNTIL ALL PDFs HAVE BEEN GENERATED
}
这样您就可以避免创建,跟踪和等待每个单独的任务; TPL为你做了一切。
答案 1 :(得分:2)
您需要获取任务列表,然后使用Task.WhenAll
等待完成
var tasks = folders.Select(folder => Task.Run(() => generatePDF(...)));
await Task.WhenAll(tasks);
如果您不能或不想使用async/await
,可以使用:
Task.WaitAll(tasks);
它将阻止当前线程,直到完成所有任务。所以如果可以,我建议使用第一种方法。
您还可以使用Parallel
C#类:
Parallel.ForEach(folders, folder => generatePDF(...));
请参阅this answer,选择哪种方法最适合您的问题。
答案 2 :(得分:0)
.NET有一个方便的方法:Task.WhenAll(IEnumerable<Task>)
在继续之前,它将等待IEnumerable中的所有任务完成。这是async
方法,因此您需要await
。
var tasks = new List<Task>();
foreach(string folderPath in folders) {
tasks.Add(Task.Run(() => generatePdf()));
}
await Task.WhenAll(tasks);