我不确定这里发生了什么。据我了解,一旦方法遇到 await 关键字,它就会有效返回,并在 Task
完成后继续执行。但是,这不是我观察到的行为。我有两个简单的方法:
public static async Task<bool> Level1()
{
var t = await Level2();
Console.WriteLine("L1 done.");
return t;
}
public static async Task<bool> Level2()
{
int delay = 10;
Thread.Sleep(100);
var t = new TaskFactory();
t.StartNew(() => { Thread.Sleep(delay); });
Console.WriteLine("L2 done.");
return true;
}
主要是,我调用
static void Main(string[] args)
{
Level1();
Console.WriteLine("Main done.");
}
现在,我希望 Main()
在调用 Level1()
之后继续执行,因为它没有被等待,并且因为 Level1()
包含一个 await 关键字。然而,结果输出是
L2 done.
L1 done.
Main done.
表示我的异步方法正在同步运行。修改 Level2()
使用 await 关键字解决问题,并且 Level1()
调用不再阻塞。为什么我需要在嵌套方法 Level2()
方法中使用“await”来防止 Level1()
阻塞 Main?
最佳答案
用 async 关键字标记方法不会使其成为异步的。它只允许使用 await(并用任务包装结果或异常)。
如果您有一个不等待其中任何异步操作的“异步”方法,则该方法是完全同步的,并将在调用线程上运行。
您可能遗漏的是,使用 await
并不一定会使方法异步运行,对未完成的任务使用 await
则可以。当任务已经完成时,没有理由暂停该方法。您可以直接从任务中获取结果并保持同步运行。
在您的情况下,Level2
同步运行。当 Level1
准备好等待其任务时,它已经完成,因此 Level2
保持同步运行。请记住,您等待的是一项任务,而不是一种方法,因此您的代码实际上是这样运行的:
public static async Task<bool> Level1()
{
var $task = Level2(); // Runs synchronously
var t = await $task; // Awaiting a completed task
Console.WriteLine("L1 done.");
return t;
}
关于c# - 没有等待的嵌套异步方法 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33048523/