2015-04-28 25 views
25

我有一個接口,公開一些異步方法。更具體地說,它定義了返回任務或任務<T>的方法。我正在使用async/await關鍵字。我應該擔心「這種異步方法缺乏'等待'運營商,並將同步運行」警告

我正在實現這個接口的過程。但是,在這些方法中的一些方法中,沒有什麼可以等待。出於這個原因,我得到了編譯器警告「這種異步方法缺乏'等待'運營商,並將同步運行...」

我明白爲什麼我得到的錯誤,但我想知道我是否應該對他們做任何事情在這上下文。忽略編譯器警告感覺不對。

我知道我可以通過在Task.Run上等待來解決它,但是對於只做一些廉價操作的方法感覺不對。這聽起來像會增加不必要的執行開銷,但是我也不確定是否已經存在,因爲存在async關鍵字。

我應該忽略警告還是有辦法解決這個問題我沒有看到?

+2

這將取決於具體情況。你確定你想要這些操作同步執行嗎?如果您確實希望它們同步執行,爲什麼該方法標記爲「異步」? – Servy

+8

只需刪除'async'關鍵字即可。你仍然可以使用Task.FromResult返回一個Task。 –

+0

在一個例子中,它確實只是給屬性分配了一些值,所以我非常適合同步執行它。關於如何處理編譯器的警告更具體一些,似乎可能是明顯的刪除異步關鍵字 – dannykay1710

回答

42

async關鍵字僅僅是方法的實現細節;它不是方法簽名的一部分。如果一個特定的方法實現或超越無關,等待,然後就省略異步關鍵字,並返回一個完成的任務使用Task.FromResult<TResult>

public Task<string> Foo()    // public async Task<string> Foo() 
{          // { 
    Baz();        //  Baz(); 
    return Task.FromResult("Hello"); //  return "Hello"; 
}          // } 

如果你的方法返回Task代替Task<TResult>,那麼你就可以返回一個完成任何類型和價值的任務。 Task.FromResult(0)似乎是一個普遍的選擇:

public Task Bar()      // public async Task Bar() 
{          // { 
    Baz();        //  Baz(); 
    return Task.FromResult(0);   // 
}          // } 

或者,如.NET框架4.6的,你可以返回Task.CompletedTask

public Task Bar()      // public async Task Bar() 
{          // { 
    Baz();        //  Baz(); 
    return Task.CompletedTask;   // 
}          // } 
+0

謝謝我認爲我錯過的一點是創建已完成的任務的概念,而不是返回像您說的那樣的具有async關鍵字的實際任務。看起來很明顯,但我只是沒有看到它! – dannykay1710

+1

任務可以使用靜態成員沿着Task.Empty的這一行進行。意圖會更清楚一點,我很難想象所有這些盡職盡責的任務都會返回一個從不需要的零。 –

+0

'await Task.FromResult(0)'?怎麼樣'等待Task.Yield()'? – Sushi271

3

一些「異步」操作完成同步完成是合理的,但爲了多態性仍符合異步調用模型。

一個真實的例子是OS I/O API。某些設備上的異步和重疊調用總是以內聯方式完成(例如,寫入使用共享內存實現的管道)。但是他們實現了與在後臺繼續執行的多部分操作相同的界面。