他们说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");
}
}
}
答案 0 :(得分: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);
}
您的代码行为如下:
await Task.Delay(3000); // Await 3 seconds...
Console.WriteLine("One"); // Once you are done awaiting, print the string...
如果您在之前>>打印字符串,则无法立即打印...
答案 1 :(得分:5)
打印"One"
需要3秒钟,因为您await
- 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);
如果在打印"One"
之前启动延迟任务而没有await
,则后续WriteLine
可以毫不拖延地完成。
答案 2 :(得分:3)
await
的工作是暂停当前方法,直到您传递给它的任何等待完成。如何,为什么以及何时创建和启动等待与await
关键字完成的内容无关。
我认为你的印象是await
开始某些东西,而事实上恰恰相反 - 它标志着代码中你要等待的一个点完成的东西。