.net 将任务分配给变量vs任务,运行[重复]

fykwrbwg  于 2023-04-07  发布在  .NET
关注(0)|答案(1)|浏览(141)

此问题已在此处有答案

await Task.Run vs await(3个答案)
Why use async and return await, when you can return Task directly?(9个答案)
昨天关门了。
我理解Task.RunTask.Factory.StartNew之间的区别,但是当我们只是将async方法分配给一些局部变量时,会发生什么呢?这三个例子的行为是否相同?
实施例1

var task1 = GetUsersAsync();
var task2 = GetCarsAsync();

await Task.WaitAll(task1,task2)

实施例2

var task1 = Task.Run(() =>  GetUsersAsync());
var task2 = Task.Run(() =>  GetCarsAsync());

await Task.WaitAll(task1,task2)

实施例3

var task1 = Task.Run(async() => await GetUsersAsync());
var task2 = Task.Run(async() => await GetCarsAsync());

await Task.WaitAll(task1,task2)
w7t8yxp5

w7t8yxp51#

这三个例子的行为是否相同
第二个和第三个在行为上没有区别(除了第三个生成冗余异步状态机,编译器甚至可以建议在这里删除async-await- @sharplab.io)
至于第一个和第二个/第三个-这取决于GetUsersAsyncGetCarsAsync的实际实现,如果它们不是真正的异步或在第一次等待之前包含重要的CPU绑定部分,那么该部分将由执行调用方法的同一个线程处理。即:

var startNew = Stopwatch.StartNew();

var task1 = GetUsersAsync();
var task2 = GetCarsAsync();

await Task.WhenAll(task1,task2);

Console.WriteLine(startNew.ElapsedMilliseconds); // Prints ~ 2100

async Task GetUsersAsync()
{
    Thread.Sleep(1000); // simulate CPU-bound work, note that changing order will change the behavior 
    await Task.Delay(100);
}

async Task GetCarsAsync()
{
    Thread.Sleep(1000);
    await Task.Delay(100);
}

Task.Run方法会在线程池上调度任务并立即返回:

var startNew = Stopwatch.StartNew();

var task1 = Task.Run(GetUsersAsync);
var task2 = Task.Run(GetCarsAsync);

await Task.WhenAll(task1,task2);

Console.WriteLine(startNew.ElapsedMilliseconds); // Prints ~ 1100

附言
在这个特定的情况下不是很相关,但对于一般理解文章-Stephen Cleary的Eliding Async and Await仍然非常有用。

相关问题