CA2007: Eine Aufgabe nicht direkt abwarten

Eigenschaft Wert
Regel-ID CA2007
Titel Eine Aufgabe nicht direkt abwarten
Kategorie Zuverlässigkeit
Fix führt oder führt nicht zur Unterbrechung Nicht unterbrechend
Standardmäßig in .NET 8 aktiviert Nein

Ursache

Eine asynchrone Methode wartet direkt auf eine Aufgabe (Task).

Regelbeschreibung

Wenn eine asynchrone Methode direkt auf eine Aufgabe (Task) wartet, erfolgt die Fortsetzung normalerweise innerhalb desselben Threads, in dem auch die Aufgabe erstellt wurde. Dies hängt jeweils vom asynchronen Kontext ab. Dieses Verhalten kann zu einer Leistungsbeeinträchtigung und einem Deadlock des Benutzeroberflächenthreads führen. Erwägen Sie, Task.ConfigureAwait(Boolean) aufzurufen, um Ihre Fortsetzungsabsicht zu signalisieren.

Behandeln von Verstößen

Rufen Sie zum Behandeln von Verstößen ConfigureAwait für die Aufgabe (Task) auf, auf die gewartet wird. Sie können für den Parameter continueOnCapturedContext entweder true oder false übergeben.

  • Das Aufrufen von ConfigureAwait(true) für die Aufgabe führt zum gleichen Verhalten, als wenn ConfigureAwait nicht explizit aufgerufen wird. Indem Sie diese Methode explizit aufrufen, teilen Sie den Lesern Ihre Absicht mit, dass Sie die Fortsetzung innerhalb des ursprünglichen Synchronisierungskontexts wünschen.

  • Rufen Sie ConfigureAwait(false) für die Aufgabe auf, um Fortsetzungen für den Threadpool zu planen und so einen Deadlock im Benutzeroberflächenthread zu vermeiden. Das Übergeben von false ist eine gute Option für Bibliotheken, für die keine Abhängigkeit von Apps besteht.

Beispiel

Mit dem folgenden Codeausschnitt wird eine Warnung generiert:

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

Rufen Sie zum Behandeln des Verstoßes ConfigureAwait für die Aufgabe (Task) auf, auf die gewartet wird:

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

Wann sollten Warnungen unterdrückt werden?

Diese Warnung ist für Bibliotheken bestimmt, bei denen der Code in beliebigen Umgebungen ausgeführt werden kann und bei denen im Code keine Annahmen getroffen werden sollten, welche Umgebung verwendet wird oder wie der Aufrufer der Methode den Aufruf durchführt oder darauf wartet. Für Projekte, in denen anstelle von Bibliothekscode Anwendungscode dargestellt wird, ist es normalerweise kein Problem, die Warnung vollständig zu unterdrücken. Das Ausführen dieses Analysetools für Anwendungscode (z. B. Schaltflächenklick-Ereignishandler in einem WinForms- oder WPF-Projekt) führt meist dazu, dass die falschen Maßnahmen ergriffen werden.

Sie können diese Warnung in allen Situationen unterdrücken, in denen die Fortsetzung wieder auf den ursprünglichen Kontext umgestellt werden soll oder in denen kein Kontext dieser Art vorhanden ist. Beim Schreiben von Code für einen Schaltflächenklick-Ereignishandler in einer WinForms- oder WPF-Anwendung sollte die Fortsetzung aus einem Wartezustand im Allgemeinen beispielsweise im Benutzeroberflächenthread ausgeführt werden. Aus diesem Grund ist das Standardverhalten wünschenswert, bei dem für die Fortsetzung die Umstellung zurück auf den ursprünglichen Kontext geplant wird. Weiteres Beispiel: Beim Schreiben von Code in einer ASP.NET Core-Anwendung sind die Elemente SynchronizationContext und TaskScheduler standardmäßig nicht vorhanden. Dies bedeutet, dass ConfigureAwait hier nicht zu einer Verhaltensänderung führt.

Unterdrücken einer Warnung

Um nur eine einzelne Verletzung zu unterdrücken, fügen Sie der Quelldatei Präprozessoranweisungen hinzu, um die Regel zu deaktivieren und dann wieder zu aktivieren.

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

Um die Regel für eine Datei, einen Ordner oder ein Projekt zu deaktivieren, legen Sie den Schweregrad in der Konfigurationsdatei auf none fest.

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

Weitere Informationen finden Sie unter Vorgehensweise: Unterdrücken von Codeanalyse-Warnungen.

Konfigurieren des zu analysierenden Codes

Mit den folgenden Option können Sie konfigurieren, für welche Teile Ihrer Codebasis diese Regel ausgeführt werden soll.

Sie können alle diese Optionen nur für diese Regel, für alle zutreffenden Regeln oder für alle zutreffenden Regeln in dieser Kategorie (Zuverlässigkeit) konfigurieren. Weitere Informationen finden Sie unter Konfigurationsoptionen für die Codequalitätsregel.

Ausschließen von Async Void-Methoden

Sie können konfigurieren, ob Sie asynchrone Methoden, die keinen Wert zurückgeben, von dieser Regel ausschließen möchten. Fügen Sie einer .editorconfig-Datei Ihres Projekts das folgende Schlüssel-Wert-Paar hinzu, um diese Arten von Methoden auszuschließen:

# 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

Ausgabetyp

Sie können auch konfigurieren, auf welche Arten von Ausgabeassemblys diese Regel angewendet werden soll. Fügen Sie einer .editorconfig-Datei in Ihrem Projekt das folgende Schlüssel-Wert-Paar hinzu, wenn diese Regel beispielsweise nur auf Code angewendet werden soll, mit dem eine Konsolenanwendung oder eine dynamisch verknüpfte Bibliothek (also keine Benutzeroberflächen-App) erstellt wird:

dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary

Siehe auch