提问人:Kevin 提问时间:4/2/2023 更新时间:4/2/2023 访问量:51
LINQ AsParallel.Select(SynchronousAction) 与 Task.Run(SynchronousAction) 的优点
Advantages of LINQ AsParallel.Select(SynchronousAction) versus Task.Run(SynchronousAction)
问:
这个问题是关于如何以 async/await 或 Task.Run() 方式处理第三方同步文件读取方法。我有一个包含 50+ 传入路径名的列表,我用它们来处理以使用更多线程。但是,可以想象,语句中的所有线程在进行同步工作时可能会阻塞并等待一小段时间。这是我应该担心的事情吗?.AsParallel
AsParallel
PathReadAndProcessOne(path)
某些线程(我的线程或线程池线程)必须运行并等待第三方文件处理器完成。我的调用线程除了等待处理路径名外别无他法,因此我不确定是否使用异步来释放我的调用线程是否重要。
LINQ+ 同步代码和下面的 Task.Run+ 异步代码的运行时间大致相同。
以一种或另一种方式编写代码是否有概念或未来优势?
// the LINQ+synchronous version - only one line of code
var nestedActions = paths.AsParallel().Select(PathReadAndProcessOne).ToList();
// The Task.Run() async version - ASYNC ALL THE WAY DOWN
//
// loop over all paths and kick off a Task.Run for each one.
var allTasks = new List<Task<List<ActionItem>>>();
foreach (var path in paths) {
var t1 = Task.Run(() => PathReadAndProcessOne(path));
allTasks.Add(t1);
}
// after all tasks are started in the loop, await them all outside the loop
try {
Task.WaitAll();
}
catch {
return false;
}
// pull out the results and aggregate them
var nestedActions = new List<ActionItem>();
foreach (var t in allTasks) {
nestedActions.AddRange(t.Result);
}
答:
1赞
Stephen Cleary
4/2/2023
#1
通常,我建议在有多个任务时使用 或 PLINQ()。 低一个抽象级别,将任务排队到线程池中。 PLINQ 具有分区逻辑,用于将工作调度到一组任务上,而这些任务是调度到线程池上的任务。因此,特别是对于大型工作负载,出于这个原因,我推荐 / PLINQ。在 PLINQ 之间,如果您的操作有结果,则 PLINQ 更易于使用,而您的操作也是如此。Parallel
AsParallel
Task.Run
Parallel
Parallel
Parallel
我的调用线程除了等待处理路径名外别无他法,因此我不确定是否使用异步来释放我的调用线程是否重要。
不,在这种情况下没关系。如果您最终在异步很重要的地方(即从 GUI 线程)使用它,那么您可以将并行代码包装在一个 .Task.Run
评论
1赞
Kevin
4/2/2023
很好的答案 - 谢谢!(哈哈,就像你以前做过一样......我刚刚发现了你所有的作品,正在疯狂地阅读以了解一切!
评论