簡體   English   中英

在異步功能中我為什么要等待?

[英]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 returnreturn 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); 
}

關於returnasync/await的故事是一樣的。 對於返回類型為Task方法,您可以返回Task或使用async/await

對於Task<T>如果你使用await你必須返回T但你不能返回Task<T>因為該方法被編譯到狀態機,那么方法必須返回T (對於Task方法無效)

如果你不使用async/await方法將完全像其他常規方法。

當您使用await - 控制流可能會保留當前方法並返回給調用者。 假設DoSomethingAsync是一些長時間運行的操作。 你打電話給SomeMethod DoSomethingAsync任務已啟動,但您不能等到它在該方法內完成 - 否則什么都不會是“異步”。 因此控制流離開Method並且應該向調用者提供返回值。 返回值是完成整個SomeMethod時完成的任務。 它可以在有或沒有結果的情況下完成( TaskTask<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.

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