Wenn Sie in C # eine Methode überschreiben, ist es zulässig, die Überschreibung asynchron auszuführen, wenn dies bei der ursprünglichen Methode nicht der Fall 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 unterbrochen. IIS protokollierte Ausnahmen mit der Meldung "Ein asynchrones Modul oder Handler wurde abgeschlossen, während ein asynchroner Vorgang noch ausstand". Einige async void
Suchanfragen ließen mich vermuten, dass jemand Missbrauch betrieben hatte , aber meine schnelle Suche in der Quelle konnte nichts finden.
Leider habe ich nach 'async \ svoid' (Regex-Suche) gesucht, als ich nach etwas ähnlichem wie 'async \ s [^ T]' hätte suchen sollen (vorausgesetzt, Task ist nicht vollständig qualifiziert ... Sie haben es verstanden).
Was ich später fand, war async override void onActionExecuting(...
in einem Basiscontroller. Das musste natürlich das Problem sein, und das war es auch. Das Problem wurde behoben, indem es für den Moment synchronisiert wurde.
Zurück zur Frage: Warum können Sie eine Außerkraftsetzung als asynchron markieren, wenn der aufrufende Code sie niemals erwarten könnte?
Task
.Antworten:
Mit dem Schlüsselwort async kann die Methode die
await
Syntax innerhalb ihrer Definition verwenden. Ich kannawait
für jede Methode, die einenTask
Typ zurückgibt, unabhängig davon, ob es sich um eine asynchrone Methode handelt.void
Ist ein zulässiger (wenn auch nicht empfohlener ) Rückgabetyp für eine asynchrone Methode. Warum sollte dies nicht zulässig sein?async
Aktiviert von außen nichts, was man ohne nicht machen könnte. Die Methode, mit der Sie Probleme haben, wurde möglicherweise so geschrieben, dass sie sich genauso verhält, ohne asynchron zu sein. Seine Definition wäre nur ausführlicher gewesen.Anrufer, ein
async T
ist Verfahren ein normales Verfahren , dass zurückkehrtT
(die begrenzt istvoid
,Task
oderTask<A>
). Dass es sich um eine asynchrone Methode handelt, gehört nicht zur Schnittstelle. Beachten Sie, dass der folgende Code illegal ist:Es (oder ein ähnlicher Code in einer abstrakten Klasse) erzeugt die folgende Fehlermeldung in VS2012:
Wenn ich habe eine Methode in einer Schnittstelle oder Elternklasse beabsichtigt typischerweise asynchron zu sein, kann ich nicht verwenden
async
, die miteinander zu kommunizieren. Wenn ich es mit derawait
Syntax implementieren wollte , müsste ich in der Lage sein, asynchrone Überschreibungsmethoden zu haben (im Fall der Elternklasse).quelle
override
überhaupt nicht, aber darum geht es in der Frage.async
die Schnittstelle einer Methode nicht geändert wird, sondern nur das, was in der Definition syntaktisch zulässig ist. Ob es sich also um eine Überschreibung handelt oder nicht, ist völlig irrelevant.async
Modifikator nur auf Implementierungen angewendet werden kann. Sie können eine Methode nicht als asynchron in einer Schnittstelle deklarieren, indem Sie beispielsweise unterstreichen, dass eine asynchrone Methode nicht Teil der Schnittstelle ist.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, die Option zum Abwarten einer Anmeldung zu verwenden. Für eine Funktion, die nicht als asynchron markiert ist, können Sie eine Variable mit dem Namen wait ohne Probleme 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.
quelle