![](/img/trans.png)
[英]Async & Await in C#: Do I have to change the entire Call Chain Up to a Void Method?
[英]Why do we have to await an async method call in C#
在 C# 中,當我們調用異步方法時,需要在方法內等待它,否則編譯器會發出警告消息說該方法將被稱為同步而沒有“等待”。 我知道這在以下情況下很有用:
var task = DoSomethingLongAsync();
DoSomethingElse();
await task;
那是因為當我們調用該異步方法時,我們可以做其他事情,然后等待異步結果。
但在其他一些情況下,我們不需要等待異步結果,比如類似於 web 服務器的場景:
listen();
while (true)
{
var request = Accept();
await ProcessRequestAsync(request);
}
顯然,對於上述場景,我們希望請求可以並行處理。 但是如果我們在那里使用 await (作為當前的),請求將被一一處理,而不是我們預期的那樣。
那么在類似的場景中我們應該如何調用異步方法呢?
您不必使用await
- 這是一個警告,而不是錯誤。
編譯器給你這個警告是因為async
方法的通常用例是異步運行它們,為此,你使用await
關鍵字。
基本上,此警告是編譯器提醒您注意的方式,以確保不會忽視 go - 但它不會阻止您在沒有await
關鍵字的情況下使用async
方法 - 您的代碼將編譯並運行。
如果您可以查看此文檔,則可以看到:
await 運算符不會阻塞評估異步方法的線程。
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/await
所以如果你不想阻塞你的線程。 你應該使用等待。 這就是我們異步設計方法的方式!
如果您將方法設計為異步並在沒有等待的情況下調用它。 這意味着你應該得到警告:)
正如@Zohar Peled 所寫,這只是一個警告。
寫下以下內容,讓別人清楚你的意圖。
換句話說,只需丟棄生成的任務,因為在這種情況下它與您無關。
listen();
while (true)
{
var request = Accept();
_ = ProcessRequestAsync(request);
}
大多數時候,不等待異步方法調用完全沒問題。
您可以只接受生成的任務,並將其保留以備后用
var requestTask = ProcessRequestAsync(request);
或者獲取一組任務然后等待它們全部完成,它們將並行工作
var task1 = ProcessRequestAsync(request1);
var task2 = ProcessRequestAsync(request2);
var task3 = ProcessRequestAsync(request3);
await Task.WhenAll(new [] { task1, task2, task3 });
或者只是第一個,在其他人還在工作的時候用它做點什么。
await Task.WhenAny(new [] { task1, task2, task3 });
您不必等待其中任何一個,只要您的應用程序仍在運行,任務就會運行並完成。
如果您厭倦了看到這些編譯器警告,您可以告訴 VS 忽略它們。
#pragma warning disable 4014
service.DoSomethingAsync();
#pragma warning restore 4014
我通常發現這些警告很有幫助,所以我只在不需要等待它們完成的“即發即棄”異步調用中禁用它們(例如,日志記錄)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.