Task.Delay是如何工作的?

Lyr*_*yrk 4 c# asynchronous

他们说Task.Delay()是一个异步的Thread.Sleep().为了测试这个我写下面的代码.我希望立即打印"One",然后3秒后打印结果变量(15).在此之后2秒,将打印"Two".但它似乎并非如此."One"不会立即打印出来.3秒后打印"One".为什么要等3秒才能打印"One"?

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication31
{
class Program
{
    public static int Multiply(int a, int b)
    {
        return a * b;
    }

    public static async Task DoRunAsync(int m, int n)
    {
        int result = await Task.Run(() => Multiply(m, n));
        await Task.Delay(3000);
        Console.WriteLine("One");
        Console.WriteLine(result);
    }

    static void Main(string[] args)
    {
        Task t = DoRunAsync(3, 5);
        Thread.Sleep(5000);
        Console.WriteLine("Two");
    }
}
}
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 7

的工作await是暂停当前方法,直到您传递给它的任何等待完成。如何,为什么以及何时创建和启动该可等待对象与await关键字完成的内容无关。

我认为您的印象是await 开始某事,而实际上恰恰相反 - 它标志着您的代码中等待某事完成的点


Tom*_*zzo 5

DoRunAsync如下修改您的方法将使事情按预期工作:

public static async Task DoRunAsync(int m, int n)
{
    int result = await Task.Run(() => Multiply(m, n));
    Console.WriteLine("One"); // before the delay, not after...
    await Task.Delay(3000);
    Console.WriteLine(result);
}
Run Code Online (Sandbox Code Playgroud)

您的代码行为如下:

await Task.Delay(3000); // Await 3 seconds...
Console.WriteLine("One"); // Once you are done awaiting, print the string...
Run Code Online (Sandbox Code Playgroud)

如果您打印字符串之前等待,则不能指望它立即打印...


das*_*ght 5

它需要3秒钟,以打印"One",因为你await-ed Task.Delay太快。

更改代码,如下所示以获取所需的结果:

int result = await Task.Run(() => Multiply(m, n));
var taskDelay = Task.Delay(3000); // No blocking here, so
Console.WriteLine("One");                              // printing can proceed.
await taskDelay; // This causes a block for the remainder of 3 seconds
Console.WriteLine(result);
Run Code Online (Sandbox Code Playgroud)

当您在打印之前启动延迟任务时"One"不带await-ing命令时,后续任务WriteLine可以毫无延迟地完成。