c# - 将列表转换为带有或不带有 Task.Run 的任务列表?
问题描述
所以我知道 Task.Run 基本上使代码在线程池的新线程中运行。但是,如果我这样做有什么区别:
var tasks = new List<string>(){ "foo", "bar" }
.Select(e => Task.Run(async () => await Process(e)))
.ToList();
await Task.WhenAll(tasks);
对比
var tasks = new List<string>(){ "foo", "bar" }
.Select(async e => await Process(e))
.ToList();
await Task.WhenAll(tasks);
我的理解是,第二个片段在等待某个异步进程时一次只运行一个,而第一个片段实际上在线程池中的线程上并行运行它们?
解决方案
这两种方法都会实例化一个任务列表,然后将await
它们完成。通常它们之间应该没有区别,除非该ProcessAsync
方法返回已经完成的任务(除非它同步运行,换句话说)。例如下面的实现:
async Task ProcessAsync(string arg)
{
Thread.Sleep(1000); // Simulate some heavy calculation
await Task.CompletedTask;
}
...阻塞当前线程 1000 毫秒,然后返回一个已完成的任务。此实现将仅与第一种方法(带Task.Run
)并行运行,并将与第二种方法(不带Task.Run
)按顺序运行。原因是创建任务成本高(所有工作都在创建过程中完成),等待任务成本低(任务已经完成)。基本上,Task.Run
您可以将昂贵的工作转移到ThreadPool
线程上。
推荐阅读
- html - 如何使用 webpack 将原始静态 html 文件包含到另一个 html 文件中
- javascript - 错误类型错误:无法设置未定义的属性“分页器”
- python - 命名管道的清洁/冲洗
- node.js - 在 Express 调用中定义查询
- python - pyqt5 使用标签管理布局
- laravel - Laravel New Project - Permission Denied
- android - QuickMatch onJoinedRoom 出现错误 2
- java - 如何在java中更改对象类型
- neo4j - 在 neo4j 中格式化时间持续时间
- selenium - 在 DDEV 容器中使用 Behat Drupal Extension 运行 selenium 测试