[英]Async and await: Why doesn't an async method whose signature defines a return type of Task explicitly return a Task?
[英]async Task method that doesn't need to await
我有一組從基類繼承的命令。 基類具有以下聲明:
public virtual async Task Execute(object parameter){}
繼承類提供了此方法的覆蓋,並非所有類都等待任務。 在這些情況下,編譯器會生成警告:
這種異步方法缺少“等待”運算符並將同步運行。 考慮使用'await'運算符等待非阻塞API調用,或'await Task.Run(...)'在后台線程上執行CPU綁定工作。
明確提供任務完整返回值是否正確?
public override async Task Execute(object parameter) {
//code containing no await statements...
await Task.CompletedTask;
}
您應該避免在重寫方法中使用async
關鍵字,這些方法不會await
任何事情,而只是返回Task.CompletedTask
:
public override Task Execute(object parameter) {
//code containing no await statements...
return Task.CompletedTask; // or Task.FromResult(0) for older .NET versions
}
這是針對此類“模擬”任務的(少數)用例之一,您可以通過查看有關Task.FromResult
問題來 Task.FromResult
。 這些注意事項對Task.CompletedTask
仍然有效。
作為一個對位, 存在例外情況的處理方式不同。
如果async
版本中的同步代碼引發異常,則會將該異常直接引發給調用者(對於具有異步簽名的方法,這種情況非常罕見)。
如果async
版本中的同步代碼引發異常,則捕獲該異常並將其置於返回的任務上(這是具有異步簽名的方法的預期行為)。
因此,如果這樣調用方法,則不同的實現將具有不同的異常語義:
var task = Execute(parameter); // non-async exceptions raised here
...
await task; // async exceptions raised here
但是大多數情況下,該方法被調用並立即等待,因此這兩個語義合並在一起:
await Execute(parameter); // both async and non-async exceptions raised here
這可能無關緊要,但我相信這是一個重要的區別。
如果異常語義對您很重要,那么您確實希望使用async
在同步代碼周圍生成狀態機,並且可以在代碼中禁用警告:
#pragma warning disable 1998 // use async keyword to capture exceptions
public override async Task Execute(object parameter) {
#pragma warning restore 1998
//code containing no await statements...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.