共用方式為


CA2007:不直接等候工作

屬性
規則識別碼 CA2007
職稱 不直接等候工作
類別 可靠性
修正程式是中斷或非中斷 不中斷
預設在 .NET 9 中啟用 No

原因

非同步方法會直接等候Task

檔案描述

當異步方法直接等候 Task 時,接續通常會發生在建立工作的相同線程中,視異步內容而定。 此行為在效能方面的成本可能很高,而且可能會導致 UI 執行緒上的死結。 請考慮呼叫 Task.ConfigureAwait(Boolean) 以發出接續意圖的訊號。

如何修正違規

若要修正違規,請在等候Task的 上呼叫 ConfigureAwait 。 您可以傳遞 truefalsecontinueOnCapturedContext 參數。

  • 在工作上呼叫 ConfigureAwait(true) 的行為與未明確呼叫 ConfigureAwait相同。 藉由明確呼叫這個方法,您會讓讀取者知道您想要在原始同步處理內容上執行接續。

  • 呼叫 ConfigureAwait(false) 工作以排程線程集區的接續,藉此避免UI線程上的死結。 傳遞是應用程式獨立連結 false 庫的絕佳選項。

範例

下列代碼段會產生警告:

public async Task Execute()
{
    Task task = null;
    await task;
}

若要修正違規,請在等候Task的 上呼叫 ConfigureAwait

public async Task Execute()
{
    Task task = null;
    await task.ConfigureAwait(false);
}

隱藏警告的時機

此警告適用於連結庫,其中程式代碼可能會在任意環境中執行,以及程式代碼不應該假設環境,或方法的呼叫者如何叫用或等候它。 通常適合針對代表應用程式程式代碼而非連結庫程式碼的項目隱藏警告;事實上,在應用程式程式代碼上執行此分析器(例如,WinForms 或 WPF 專案中的按鈕按兩下事件處理程式)可能會導致採取錯誤的動作。

您可以在任何應將接續排程回原始內容或不存在這類內容的情況下,隱藏此警告。 例如,在 WinForms 或 WPF 應用程式中撰寫程式代碼時,一般而言,await 的接續應該在 UI 線程上執行,因此需要將接續排程回原始內容的預設行為。 另一個範例是,在 ASP.NET Core 應用程式中撰寫程式代碼時,預設沒有 SynchronizationContextTaskScheduler,因此 ConfigureAwait 不會實際變更任何行為。

隱藏警告

如果您只想要隱藏單一違規,請將預處理器指示詞新增至原始程式檔以停用,然後重新啟用規則。

#pragma warning disable CA2007
// The code that's violating the rule is on this line.
#pragma warning restore CA2007

若要停用檔案、資料夾或項目的規則,請在組態檔中將其嚴重性設定為 。none

[*.{cs,vb}]
dotnet_diagnostic.CA2007.severity = none

如需詳細資訊,請參閱 如何隱藏程式代碼分析警告

設定程式代碼以分析

使用下列選項來設定程式代碼基底要執行此規則的部分。

您可以只針對此規則、針對它套用的所有規則,或針對套用至此類別的所有規則,或針對它套用的所有規則,設定所有選項。 如需詳細資訊,請參閱 程式代碼品質規則組態選項

排除異步 void 方法

您可以設定是否要排除不從此規則傳回值的異步方法。 若要排除這類方法,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

# Package version 2.9.0 and later
dotnet_code_quality.CA2007.exclude_async_void_methods = true

# Package version 2.6.3 and earlier
dotnet_code_quality.CA2007.skip_async_void_methods = true

輸出種類

您也可以設定要套用此規則的輸出元件類型。 例如,若要只將此規則套用至產生主控台應用程式或動態連結庫的程式代碼(也就是UI應用程式),請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary

另請參閱