我想通过HttpClient
以异步方式从各种服务下载数据(出于测试目的,我用Task.Delay
创建了几个方法)。因此,首先,我决定创建任务列表,并最终使用await Task.WhenAll(tasks)
等待一切。
一切都是我想要的,但是如果我把lambda传递给tasks.Add()
,就会有一个问题。我必须使用Task.Run
,因为没有它就不能使用,等待内部。
所以我的问题是:
这个Task.Run()
会产生额外的开销吗?因为对于I/O绑定操作,我们不应该使用Task.Run
,而应该使用简单的异步等待。
class Program
{
public static async Task<int> DownloadDelay15()
{ await Task.Delay(15000); return 15; }
public static async Task<int> DownloadDelay2()
{ await Task.Delay(1000); return 2; }
static async Task Main(string[] args)
{
var tasks = new List<Task<int>>();
tasks.Add(DownloadDelay15());
tasks.Add(DownloadDelay2());
tasks.Add(Task.Run(async () => //additional overhead?
{
await Task.Delay(1000);
return 6;
}));
var watch = Stopwatch.StartNew();
var results = await Task.WhenAll(tasks);
watch.Stop();
var elapsedSeconds = watch.Elapsed.Seconds;
}
}
发布于 2020-01-14 21:14:53
如果我将lambda传递给tasks.Add(),则为tasks.Add()。我必须使用Task.Run,因为没有它就不能使用,等待内部。
不能将lambda传递给Add
;需要将Task
传递给Add
。您可以通过创建另一个方法来做到这一点:
async Task<int> DownloadDelay6()
{
await Task.Delay(1000);
return 6;
}
var tasks = new List<Task<int>>();
tasks.Add(DownloadDelay15());
tasks.Add(DownloadDelay2());
tasks.Add(DownloadDelay6());
这个Task.Run()会产生附加开销吗?因为对于IO绑定操作,我们不应该使用Task.Run,而应该使用简单的异步等待。
是的;Task.Run
在线程池线程上运行它的委托,因此有一些额外的开销。它不是很多,但它在那里。
发布于 2020-01-14 22:25:57
如果您想要将lambda传递给您的列表,我建议您将其设置为委托列表,而不是任务列表。然后,您可以将其转换为任务列表,以便等待它。
static async Task Main(string[] args)
{
var jobs = new List<Func<Task<int>>>
{
DownloadDelay15,
DownloadDelay2,
async () => { await Task.Delay(1000); return 6; }
};
var tasks = jobs.Select(job => job()).ToList();
var watch = Stopwatch.StartNew();
var results = await Task.WhenAll(tasks);
watch.Stop();
var elapsedSeconds = watch.Elapsed.Seconds;
}
为了回答您的问题,是的,Task.Run
会造成一些开销,因为以这种方式执行的任务会放在线程池上。
发布于 2020-01-14 22:23:20
如果你用Task.Run
..。
这听起来可能自相矛盾。假设您将在一台多核计算机上运行,您的程序将运行得更快的原因是任务将并行启动。如果您的任务可以启动,CPU要求为零,并且您的示例中的任务就是这样,则这可能与此无关,但并非所有任务都可以立即启动。有些任务包括在任务启动之前运行的同步代码。如果没有Task.Run
,这个同步代码将按顺序运行,因为一个任务将一个接一个地启动。使用Task.Run
,同步代码将在所有可用内核中并行运行。Task.Run
的额外开销将由整个系统支付,而不仅仅由您的程序支付。开销很小,每次调用大约有2微秒的CPU时间,所以很可能您也不会注意到任何不同,除非您一次运行数十万个任务。
https://stackoverflow.com/questions/59741440
复制相似问题