簡體   English   中英

async不需要等待的任務方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM