簡體   English   中英

等待 Task.CompletedTask 與返回

[英]await Task.CompletedTask vs return

我試圖了解await Task.CompletedTaskreturn之間的區別,但似乎找不到任何明確定義的解釋。

為什么/什么時候使用這個:

public async Task Test()
{
    await Task.CompletedTask;
}

在這個?

public async Task Test()
{
    return;
}

據我了解,兩者的status都將設置為TaskStatus.RanToCompletion雖然我覺得這可能與物理時間有關,或者基於Task.FromResult的解釋:

該方法通常在無需執行更長的代碼路徑即可立即知道任務的返回值時使用。

由於我已經研究了 GitHub 上的 MS 代碼、MS Docs 以及我能找到的每個鏈接,因此希望能清楚地揭開這一點,但它沒有給出明確的解釋。 我還在更大的方法末尾看到await Task.CompletedTask ,根據我 在 GitHub 上從 MS發現的一些評論實際上是錯誤的,因為它不應該包含它,他們希望將其從存儲庫中清除。

如果對Task.FromResult (因為他們是兄弟姐妹)也有一個明確的揭秘,那將不勝感激,因為我仍然不清楚何時使用:

public async Task<bool> Test()
{
    return await Task.FromResult(true);
}

對此:

public async Task<bool> Test()
{
    return true;
}

讓我們從消費者的角度來看問題。

如果您定義了一個接口,該接口強加了一個返回Task的操作,那么您實際上並沒有說明它將如何計算/執行(因此,方法簽名中沒有async訪問修飾符)。 這是一個實現細節

界面

public interface ITest
{
    Task Test();
    Task<bool> IsTest();
}

因此,如何實現接口取決於您。

您可以以同步方式執行此操作,因為沒有async關鍵字而不會生成任何AsyncStateMachine

實施#1

public class TestImpl : ITest
{
    public Task Test()
    {
        return Task.CompletedTask;
    }

    public Task<bool> IsTest()
    {
        return Task.FromResult(true);
    }
}

或者您可以嘗試以異步方式實現它,但不使用await運算符。 在這里您將收到 CS1998 警告。

實施#2

public class TestImpl : ITest
{
    public async Task Test()
    {
        return;
    }

    public async Task<bool> IsTest()
    {
        return true;
    }
}

此異步方法缺少“等待”運算符,並且將同步運行。 考慮使用 'await' 運算符來等待非阻塞 API 調用,或使用 'await Task.Run(...)' 在后台線程上執行 CPU 密集型工作。

換句話說,這個實現沒有定義一個狀態機。 async 方法根據await關鍵字分為不同的狀態:

  • before_the_await_1,
  • after_the_await_1_but_before_the_await_2
  • after_the_await_2_but_before_the_await_3
  • ...

如果您沒有任何等待,那么您將擁有一個狀態,它將同步運行(無需保留狀態,執行異步操作,然后調用MoveNext() )。


或者您可以嘗試使用await運算符以異步方式實現它。

實施#3

public class TestImpl : ITest
{
    public async Task Test()
    {
        await Task.CompletedTask;
    }

    public async Task<bool> IsTest()
    {
        return await Task.FromResult(true);
    }
}

在這種情況下,將有一個異步狀態機,但不會在堆上分配。 默認情況下,它是一個struct ,如果它同步完成,那么我們不需要在堆上分配它們以將其生命周期延長到方法的范圍之外。

有關更多信息,請閱讀以下文章:

return; 表示您退出 function

await Task.CompletedTask; 只需繼續執行 function 主體的 rest 即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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