以下示例为何被阻止?我原以为“首先运行”会立即运行,然后5秒钟后会出现“最后运行”。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Call SomeAsyncCode() somehow
SomeAsyncCode().GetAwaiter().GetResult();
Console.WriteLine("Run First");
}
private static async Task SomeAsyncCode()
{
// Use await here!
await Task.Delay(5000);
Console.WriteLine("Run Last");
// Other async goodness...
}
}
}
答案 0 :(得分:5)
您正在等待(松散使用该术语)任务。
如果您不使用.GetAwaiter().GetResult();
(无论如何都是内部框架方法)而只是编写
SomeAsyncCode().Wait();
Console.WriteLine("Run First");
然后事情就变得很明显了,您正在等待任务完成。
以下内容可能更符合您的期望;
// start task
var task = SomeAsyncCode();
Console.WriteLine("Run First");
task.Wait();
但是,老实说,很少需要使用Wait
方法调用Result
,GetAwaiter().GetResult()
或async
,而在中进行调用UI 应用程序或带有 Synchronization Context 的内容可能会导致死锁
理想情况下,您让async
和await
在 C#7.1 及更高版本中传播,您可以创建async
入口点,您可以更简洁地使用异步和等待模式
static async Task Main(string[] args)
{
await SomeAsyncCode();
Console.WriteLine("Run First");
}
或
static async Task Main(string[] args)
{
var task = SomeAsyncCode();
Console.WriteLine("Run First");
await Task.WhenAll(task);
}
答案 1 :(得分:1)
定义async Task Method()
时-告诉您应该等待此方法,即使它不会返回任何内容。
定义async void Method()
时-告诉您这是 fire'n'forget 方法,您不想等待它。
此外,当void Main(string[] args)
返回时-您的应用程序正在关闭,GC将终止所有任务。
因此,您的代码应更像这样:
static void Main(string[] args)
{
// Call SomeAsyncCode() somehow
SomeAsyncCode();
Console.WriteLine("Run First");
Console.ReadKey(); // you need this to prevent app from closing
}
private static async void SomeAsyncCode()
{
// Use await here!
await Task.Delay(5000);
Console.WriteLine("Run Last");
// Other async goodness...
}