C#中的异步Main并阻止异步Http调用

ale*_*aka 0 c# concurrency async-await dotnet-httpclient .net-core

我对我认为纯粹是异步程序的输出感到困惑。如您所见,没有明显的反模式(希望如此)和阻止呼叫。

slowURL限制服务器响应10秒钟。我确实通过在10秒钟的超时时间内运行对本地服务器的调用来确认,FetchSlowAsync在控制台中运行代码时,该方法调用有效地阻塞了主线程10秒钟。

我希望TaskScheduler不会按顺序安排调用,而是总是随机确定方法的调用顺序。las,输出始终是确定性的。

FetchSlowAsync start
FetchSlowAsync got data!
FetchAsync start
FetchAsync got data!
FetchBingAsync start
FetchBingAsync got data!
All done!
Run Code Online (Sandbox Code Playgroud)

我的问题是:是什么促使FetchSlowAsync阻塞而不是TaskScheduler执行上下文切换到另一个异步方法,并在完成后返回到它?

下一个问题是前一个问题:async Main在异步执行模型是并发的情况下,为什么其中的所有方法都按照被调用的相同顺序执行?

FetchSlowAsync start
FetchSlowAsync got data!
FetchAsync start
FetchAsync got data!
FetchBingAsync start
FetchBingAsync got data!
All done!
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

当前,您正在等待返回的任务FetchSlowAsync()完成,然后再继续进行呼叫FetchBingAsync等。您可以通过等待任务来完成此任务,这里:

await FetchSlowAsync();
await FetchBingAsync();
await FetchAsync();
Run Code Online (Sandbox Code Playgroud)

如果您不想在启动Bing提取等之前等待缓慢的提取完成,则可以记住它们返回的任务,并在以后等待它们:

static async Task Main()
{
    // Start all three tasks
    Task t1 = FetchSlowAsync();
    Task t2 = FetchBingAsync();
    Task t3 = FetchAsync();

    // Then wait for them all to finish
    await Task.WhenAll(t1, t2, t3);

    await Console.Out.WriteLineAsync("All done!");
}
Run Code Online (Sandbox Code Playgroud)

现在您得到了我认为您期望的那种输出。例如,这是在我的机器上运行的:

FetchSlowAsync start
FetchBingAsync start
FetchAsync start
FetchAsync got data!
FetchBingAsync got data!
FetchSlowAsync got data!
All done!
Run Code Online (Sandbox Code Playgroud)