| 屬性 | 值 |
|---|---|
| 規則識別碼 | CA2007 |
| 職稱 | 不要直接等待任務 |
| 類別 | 可靠性 |
| 修正是造成中斷還是不中斷 | 不中斷 |
| 在 .NET 10 中預設啟用 | 否 |
| 適用語言 | C# 與 Visual Basic |
原因
規則描述
當非同步方法直接等候 Task 時,接續通常會發生在建立該工作的相同執行緒中,這取決於非同步上下文。 此行為在效能方面的成本可能很高,而且可能會導致 UI 執行緒上的死結。 請考慮呼叫 Task.ConfigureAwait(Boolean) 以發出接續意圖的訊號。
如何修正違規
若要修正違規,請在等待的Task上呼叫ConfigureAwait。 您可以傳遞 true 或 false 給 continueOnCapturedContext 參數。
在工作上呼叫
ConfigureAwait(true)的行為與未明確呼叫 ConfigureAwait相同。 藉由明確呼叫這個方法,您會讓讀取者知道您想要在原始同步處理內容上執行接續。將
ConfigureAwait(false)應用於工作以排程執行緒集區的後續,藉此避免UI執行緒上的死鎖。 在應用程式無關的函式庫中傳遞false是很好的選擇。
範例
下列代碼段會產生警告:
public async Task Execute()
{
Task task = null;
await task;
}
若要修正違規,請在等候ConfigureAwait時呼叫Task。
public async Task Execute()
{
Task task = null;
await task.ConfigureAwait(false);
}
隱藏警告的時機
此警告適用於函式庫,其中的程式碼可能在各種環境中執行,且不應假設環境或方法的呼叫者如何呼叫或等待方法。 通常適合針對代表應用程式程式代碼而非連結庫程式碼的項目隱藏警告;事實上,在應用程式程式代碼上執行此分析器(例如,WinForms 或 WPF 專案中的按鈕按兩下事件處理程式)可能會導致採取錯誤的動作。
您可以在應將續行操作排程返回原始上下文的情況下,或不存在這類上下文的情況下,隱藏此警告。 例如,當在 WinForms 或 WPF 應用程式中的按鈕點擊事件處理程序中撰寫程式碼時,一般而言,await 的後續動作應在 UI 執行緒上執行,因此預設行為是將其排程回到原始上下文,這是可取的。 另一個範例是,在 ASP.NET Core 應用程式中撰寫程式代碼時,預設沒有 SynchronizationContext 或 TaskScheduler,因此 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