Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么多个等待像Task.WhenAll()一样需要相同的时间_C#_Asynchronous_Async Await_Task_Console Application - Fatal编程技术网

C# 为什么多个等待像Task.WhenAll()一样需要相同的时间

C# 为什么多个等待像Task.WhenAll()一样需要相同的时间,c#,asynchronous,async-await,task,console-application,C#,Asynchronous,Async Await,Task,Console Application,我理解,当您有任务列表时,建议在多个wait上使用wait Task.WhenAll(),因为Task.WhenAll()处理异常的方式。但是,根据我对“async,await”工作方式的理解,我想知道为什么下面的代码块具有相同的执行时间: static void Main(string[] args) { MainAsync(args).GetAwaiter().GetResult(); Console.ReadLine(); } static async Task Main

我理解,当您有任务列表时,建议在多个
wait
上使用
wait Task.WhenAll()
,因为
Task.WhenAll()
处理异常的方式。但是,根据我对“async,await”工作方式的理解,我想知道为什么下面的代码块具有相同的执行时间:

static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
    Console.ReadLine();
}

static async Task MainAsync(string[] args)
{
    Console.WriteLine("Starts :" + DateTime.Now.ToLongTimeString());
    var firstTask = SleepForTime(10000);
    var secondTask = SleepForTime(7000);
    var thirdTask = SleepForTime(5000);

    await firstTask;
    await secondTask;
    await thirdTask;

    Console.WriteLine("Done :" + DateTime.Now.ToLongTimeString());

    Console.ReadLine();
}

public static async Task SleepForTime(int seconds)
{
    await Task.Delay(seconds);
}
此块执行时间为10秒,与此块相同:

static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
    Console.ReadLine();
}

static async Task MainAsync(string[] args)
{
    Console.WriteLine("Starts :" + DateTime.Now.ToLongTimeString());
    var firstTask = SleepForTime(10000);
    var secondTask = SleepForTime(7000);
    var thirdTask = SleepForTime(5000);

    await Task.WhenAll(firstTask, secondTask, thirdTask);

    Console.WriteLine("Done :" + DateTime.Now.ToLongTimeString());

    Console.ReadLine();
}

public static async Task SleepForTime(int seconds)
{
    await Task.Delay(seconds);
}
根据我的理解,第一个块应该需要22秒,因为
await
列表将按顺序逐个执行,因为这是微软在MSDN中解释的异步等待方式。我错过了什么?编译器是否对其进行了优化?有人能解释一下引擎盖下面发生了什么吗

根据我的理解,第一个块应该需要22秒,因为等待列表将按顺序逐个执行

不可以。在等待这三项任务之前,您正在启动所有这三项任务,因此它们都同时运行

var firstTask = SleepForTime(10000); //start the 1st Task
var secondTask = SleepForTime(7000); //start the 2nd Task
var thirdTask = SleepForTime(5000);  //start the 3rd Task

await firstTask;  //wait for the 1st Task to finish
await secondTask; //wait for the 2nd Task to finish
await thirdTask;  //wait for the 3rd Task to finish
以下操作需要22秒:

await SleepForTime(10000);
await SleepForTime(7000);
await SleepForTime(5000);

下一个任务直到上一个任务完成后才开始。

任务。延迟内部使用计时器通知程序何时应继续。当您调用
任务时,计时器立即启动。延迟
。在这两种情况下,当您将任务存储在变量中时,您会一个接一个地启动任务,直到
稍后等待它们。在等待任何一个计时器时,计时器仍在后台运行,因为它们或多或少是在同一时间启动的,所以当延迟最长的计时器结束时,计时器结束

var firstTask = SleepForTime(10000);
var secondTask = SleepForTime(7000);
var thirdTask = SleepForTime(5000);  

// All of the tasks are already started
Console.WriteLine("Start");
await firstTask;                       //this finishes after ~10s
Console.WriteLine("First finished");
await secondTask;                      //this finishes immediately
Console.WriteLine("Second finished");
await thirdTask;                       //this also finishes immediately
Console.WriteLine("Third finished");
所有
第一次/第二次/第三次完成的
消息在10秒后几乎同时显示。您可以在一些修改后看到更改:

var firstTask = SleepForTime(5000);
var secondTask = SleepForTime(7000);
var thirdTask = SleepForTime(10000);  

// All of the tasks are already started
Console.WriteLine("Start");
await firstTask;                      //this finishes after ~5s
Console.WriteLine("First finished");
await secondTask;                     //this finishes after 2 more seconds
Console.WriteLine("Second finished");
await thirdTask;                      //this finishes after 3 more seconds
Console.WriteLine("Third finished");
现在
第一次完成
在5秒后显示,第二次完成
在另一个2秒后显示,第三次完成
在另一个3秒后显示

要获得所需的结果,您必须按顺序调用函数,并在那里等待每个函数,如下所示:

Console.WriteLine("Start");
await SleepForTime(10000);            //this finishes after 10s
Console.WriteLine("First finished");
await SleepForTime(7000);             //this finishes after 7s
Console.WriteLine("Second finished");
await SleepForTime(5000);             //this finishes after 5s
Console.WriteLine("Third finished");

SleepForTime
函数是一些风格改进的完美候选者-使用后缀
Async
指示它应该在异步代码中使用,并且您可以返回从
任务返回的任务。延迟
本身使代码更简单(对于您和编译器而言)


1-在原始代码中,我试图使用
控制台.WriteLine(firstTask.status)
打印任务状态,以查看它是否正在运行,我得到:“WaitingForActivation”,我假设它应该是“running”,为什么?2-我想我可以保持代码在
mainascync
方法中的原样,并将
SleepForTime(int秒)
方法更改为:
public static Task SleepForTime(int秒){return new Task(async()=>{wait Task.Delay(10000);}
但是任何方法中的
mainascync
方法中的代码似乎都被阻塞了,它根本没有完成?有什么想法吗?
public static Task SleepForTimeAsync(int seconds)
{
    return Task.Delay(seconds);
}