[英]In async function why do I have to await?
說我有這樣的方法:
private async Task SomeMethod()
{
await DoSomethingAsync();
await DoSomethingElseAsync();
return;
}
鑒於DoSomethingElseAsync
返回一個Task
,看起來你應該能夠這樣做:
private async Task SomeMethod()
{
await DoSomethingAsync();
return DoSomethingElseAsync();
}
但編譯器抱怨這個:
由於'
SomeMethod
'是一個返回'Task
'的異步方法,因此return關鍵字后面不能跟一個對象表達式。 你打算退回'Task<T>
'嗎?
這是為什么?
它非常類似於yield return
和return
yield return
。 對於迭代器,您可以使用這些方法中的任何一種
public IEnumerable<int> SomeIterator()
{
for(int I = 0; I < 10; I++) yield return I;
}
public IEnumerable<int> SomeIterator()
{
return Enumerable.Range(0, 10); // return result of another iterator.
}
但你不能兩者兼得。 它不起作用,因為迭代器要么被編譯器轉換為類來處理帶有yield
延遲迭代,要么就像其他返回其他東西的普通方法一樣。
public IEnumerable<int> SomeIterator() // not valid
{
for(int I = 0; I < 10; I++) yield return I;
return Enumerable.Range(0, 10);
}
關於return
和async/await
的故事是一樣的。 對於返回類型為Task
方法,您可以返回Task
或使用async/await
。
對於Task<T>
如果你使用await你必須返回T
但你不能返回Task<T>
因為該方法被編譯到狀態機,那么方法必須返回T
(對於Task
方法無效)
如果你不使用async/await
方法將完全像其他常規方法。
當您使用await
- 控制流可能會保留當前方法並返回給調用者。 假設DoSomethingAsync
是一些長時間運行的操作。 你打電話給SomeMethod
。 DoSomethingAsync
任務已啟動,但您不能等到它在該方法內完成 - 否則什么都不會是“異步”。 因此控制流離開Method
並且應該向調用者提供返回值。 返回值是完成整個SomeMethod
時完成的任務。 它可以在有或沒有結果的情況下完成( Task
或Task<T>
返回值)。 因此,在await
之后返回的內容不能是SomeMethod
返回類型 - 它只能是結果類型T
(如果SomeMethod
返回Task),或者只是return
指示SomeMethod
完成返回簡單Task
。
在常規方法中, return
表示“從方法返回此值,如果有的話”。 在async
方法中, return
的含義更改為“將返回的Task
的結果設置為此值(如果有)”。
但是你無法將兩者結合起來:在async Task
方法中,你不能直接return
一個Task
。 這樣做的一個原因是,如果你await
ed,該方法實際上已經返回了一個Task
,它不能返回另一個。
在返回時, async Task
方法的行為類似於void
方法,因為它只允許return;
,但永遠不會return value;
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.