webentwicklung-frage-antwort-db.com.de

Ist es in Ordnung, eine virtuelle asynchrone Methode für die Basisklasse zu haben?

Ich arbeite mit etwas Code, wo ich 2 Klassen mit sehr ähnlicher Logik und Code habe. Ich habe protected async void LoadDataAsync() Methode für beide Klassen.
Derzeit überarbeite ich es und denke darüber nach, gemeinsame Logik in die Basisklasse zu verschieben.
Ist es in Ordnung, virtual async Methode für Basisklasse und überschreiben Sie es für abgeleitete Klassen?
Gibt es irgendwelche Probleme damit?
Mein Code sieht so aus:

public class Base
{
   protected virtual async void LoadDataAsync() {}
}

public class Derived : Base
{
   protected override async void LoadDataAsync()
   {
       // awaiting something
   }
}

Ähnlich (aber nicht gleich) Frage wurde bereits gestellt.

41

Kurze Antwort

  • Eine virtual Methode darf wird als async markiert
  • Eine abstract -Methode kann nicht als async markiert werden

Der Grund dafür ist, dass async nicht Teil der Methodensignatur ist. Es teilt dem Compiler lediglich mit, wie die Kompilierung des Methodenkörpers selbst zu handhaben ist (und gilt nicht für überschreibende Methoden). Da eine abstrakte Methode keinen Methodentext hat, ist es nicht sinnvoll, den Modifikator async anzuwenden.

Lange Antwort

Anstelle Ihrer aktuellen Signatur in der Basisklasse würde ich Folgendes empfehlen, wenn die Basisklasse eine Standardimplementierung der Methode bereitstellt, jedoch keine Arbeit ausführen muss.

protected virtual Task LoadDataAsync() {
  return Task.FromResult(default(object));
}

Die wichtigsten Änderungen aus Ihrer Implementierung sind die folgenden:

  1. Ändern Sie den Rückgabewert von void in Task (denken Sie daran, dass async nicht Teil des Rückgabetyps ist). Im Gegensatz zur Rückgabe von void kann bei der Rückgabe eines Task -Aufrufcodes Folgendes ausgeführt werden:
    • Warten Sie, bis der Vorgang abgeschlossen ist
    • Überprüfen Sie den Status der Aufgabe (abgeschlossen, abgebrochen, fehlerhaft)
  2. Vermeiden Sie die Verwendung des Modifizierers async, da die Methode nichts zu await machen muss. Geben Sie stattdessen einfach eine bereits abgeschlossene Task -Instanz zurück. Methoden, die diese Methode überschreiben, können den Modifikator async weiterhin verwenden, wenn sie ihn benötigen.
70
Sam Harwell

Ja, es ist in Ordnung, aber Sie sollten async Task Anstatt von async void. Ich habe einen MSDN-Artikel, der erklärt, warum .

19
Stephen Cleary