it-swarm.com.de

Warum können Sie mit C # eine asynchrone Überschreibung durchführen?

Wenn Sie in C # eine Methode überschreiben, ist es zulässig, die Überschreibung asynchron zu machen, wenn die ursprüngliche Methode dies nicht war. Dies scheint eine schlechte Form zu sein.

Das Beispiel, das mich dazu brachte, war das folgende: Ich wurde hinzugezogen, um bei einem Lasttestproblem zu helfen. Bei ungefähr 500 gleichzeitigen Benutzern würde der Anmeldevorgang in einer Umleitungsschleife zusammenbrechen. IIS protokollierte Ausnahmen mit der Meldung "Ein asynchrones Modul oder Handler wurde abgeschlossen, während eine asynchrone Operation noch ausstand". Einige Suchanfragen führten mich zu der Annahme, dass jemand async void Missbrauchte, aber Meine schnelle Suche in der Quelle konnte nichts finden.

Leider habe ich nach 'async\svoid' (Regex-Suche) gesucht, als ich nach etwas mehr wie 'async\s [^ T]' hätte suchen sollen (vorausgesetzt, Task war nicht vollständig qualifiziert ... Sie verstehen).

Was ich später fand, war async override void onActionExecuting(... In einem Basis-Controller. Das musste natürlich das Problem sein, und das war es auch. Das Problem wurde behoben, indem das Problem behoben wurde (für den Moment synchronisiert).

Zurück zur Frage: Warum oh, warum können Sie eine Überschreibung als asynchron markieren, wenn der aufrufende Code niemals darauf warten könnte?

17

Mit dem Schlüsselwort async kann die Methode die Syntax await in ihrer Definition verwenden. Ich kann await für jede Methode verwenden, die einen Task -Typ zurückgibt, unabhängig davon, ob es sich um eine asynchrone Methode handelt.

void ist ein legaler (wenn auch entmutigter ) Rückgabetyp für eine asynchrone Methode. Warum sollte dies nicht zulässig sein? Von außen ermöglicht async nichts, was Sie ohne es nicht tun könnten. Die Methode, mit der Sie Probleme haben, könnte so geschrieben worden sein, dass sie sich genauso verhält, ohne asynchron zu sein. Seine Definition wäre nur ausführlicher gewesen.

Für Aufrufer ist eine async T - Methode eine normale Methode, die T zurückgibt (beschränkt auf void, Task oder Task<A>). . Dass es sich um eine asynchrone Methode handelt, ist nicht Teil der Schnittstelle. Beachten Sie, dass der folgende Code unzulässig ist:

interface IFoo {
    async void Bar();
}

Es (oder ein ähnlicher Code in einer abstrakten Klasse) erzeugt die folgende Fehlermeldung in VS2012:

Der Modifikator 'async' kann nur in Methoden verwendet werden, die einen Anweisungshauptteil haben

Wenn ich beabsichtigt habe, dass eine Methode in einer Schnittstelle oder übergeordneten Klasse normalerweise asynchron ist, kann ich async nicht verwenden, um dies zu kommunizieren. Wenn ich es mit der Syntax await implementieren wollte, müsste ich in der Lage sein, asynchrone Überschreibungsmethoden zu verwenden (im Fall der übergeordneten Klasse).

17

Der einzige Zweck des asynchronen Schlüsselworts besteht darin, das Warten innerhalb des Hauptteils dieser Funktion zu einem Schlüsselwort zu machen. Dies ist erforderlich, damit das Hinzufügen der Wartefunktion den vorhandenen Code nicht beschädigt. Microsoft hat beschlossen, auf eine Opt-In-Option zu warten. Für eine Funktion, die nicht als asynchron markiert ist, können Sie ohne Probleme eine Variable mit dem Namen await definieren.

Daher ist Async nicht Teil der Signatur einer Funktion und hat im generierten IL-Code keine semantische Bedeutung. Der Compiler muss unbedingt wissen, wie die Funktion korrekt kompiliert wird. Außerdem wird der Compiler angewiesen, sicherzustellen, dass nur Task, Task <T> oder void zurückgegeben werden.

10
Eric Johnson