Ich habe eine Schnittstelle mit einigen asynchronen Funktionen. Einige der Klassen, die die Schnittstelle implementieren, müssen nicht warten, andere werfen möglicherweise nur. Es ist ein bisschen nervig mit all den Warnungen.
Wenn Sie nicht warten, warten Sie in einer asynchronen Funktion.
Ist es möglich, die Nachricht zu unterdrücken?
public async Task<object> test()
{
throw new NotImplementedException();
}
Warnung CS1998: Bei dieser asynchronen Methode fehlen die Operatoren "Warten" und sie wird synchron ausgeführt. Verwenden Sie den Operator 'await', um nicht blockierende API-Aufrufe abzuwarten, oder 'wait Task.Run (...)', um CPU-gebundene Arbeiten an einem Hintergrundthread auszuführen.
c#
asynchronous
Simon
quelle
quelle
Antworten:
Task
Ich glaube, die Methoden kehren zurück .async
ist ein Implementierungsdetail und kann daher nicht auf Schnittstellenmethoden angewendet werden.In diesen Fällen können Sie die Tatsache nutzen, dass
async
es sich um ein Implementierungsdetail handelt.Wenn Sie nichts zu tun haben
await
, können Sie einfach zurückkehrenTask.FromResult
:Beim Werfen
NotImplementedException
ist das Verfahren etwas wortreicher:Wenn Sie viele Methoden zum Werfen haben
NotImplementedException
(was selbst darauf hindeuten könnte, dass ein Refactoring auf Designebene gut wäre), können Sie die Worthaftigkeit in eine Hilfsklasse einschließen:Die Hilfsklasse reduziert auch den Müll, den der GC sonst sammeln müsste, da jede Methode mit demselben Rückgabetyp ihre
Task
undNotImplementedException
Objekte gemeinsam nutzen kann.Ich habe mehrere andere Beispiele vom Typ "Task-Konstante" in meiner AsyncEx-Bibliothek .
quelle
Task
. Stattdessen wird Ihre Methode geworfen, bevor sie überhaupt die Möglichkeit hat, eine zu erstellenTask
. Ich denke wirklich, dass das beste Muster darin besteht, eineasync
Methode ohneawait
Operatoren zu definieren . Dies stellt sicher, dass der Code innerhalb der Methode alle als Teil der behandelt wirdTask
.await Task.FromResult(0);
Ihre Methode ergänzen . Dies sollte keine signifikanten Auswirkungen auf die Leistung haben (im Gegensatz zu Task.Yield ()).return Task.CompletedTask;
- das einfachste von allen.Eine andere Option, wenn Sie den Hauptteil der Funktion einfach halten und keinen Code schreiben möchten, um ihn zu unterstützen, besteht darin, die Warnung einfach mit #pragma zu unterdrücken:
Wenn dies häufig genug ist, können Sie die disable-Anweisung oben in die Datei einfügen und die Wiederherstellung weglassen.
http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx
quelle
Eine andere Möglichkeit, das asynchrone Schlüsselwort beizubehalten (falls Sie es behalten möchten), besteht darin, Folgendes zu verwenden:
Sobald Sie die Methode ausgefüllt haben, können Sie die Anweisung einfach entfernen. Ich benutze dies sehr oft, besonders wenn eine Methode auf etwas wartet, aber nicht jede Implementierung dies tatsächlich tut.
quelle
Task.Run
Aufruf zu packen .Task.CompletedTask
nicht mehr zu existieren.Task.FromResult
die bessere Antwort zu sein. Für diese Angelegenheit, wenn Sie sind eine Ausnahme zu werfen , gehen, scheint es eine andere Antwort ins Spiel kommen , hat sich in Bezug aufTask.FromException
Herstellung dieses nie die ideale Lösung. Würdest du zustimmen?Es gibt einen Unterschied zwischen Lösungen und genau genommen sollten Sie wissen, wie der Aufrufer die asynchrone Methode aufrufen wird. Bei einem Standardverwendungsmuster, das ".Wait ()" für das Methodenergebnis voraussetzt, ist " return Task.CompletedTask " die beste Lösung.
Hinweis:
FromResult
Kann nicht direkt verglichen werden.Testcode:
}}
quelle
#pragma
eine über Kopf zu entstehen scheint. Wahrscheinlich genauso viel Aufwand, als ob Sie anstelle der Rückgabe eineCompletedTask
erstellt und abgeschlossen hättenAsyncOperation
. Es wäre schön, dem Compiler mitteilen zu können, dass es in Ordnung ist, dies zu überspringen, wenn die Methode ohnehin synchron ausgeführt wird.Task.CompletedTask
Meinung nach ähnlichTask.FromResult
? Es wäre interessant zu wissen - ich gehe davon aus, dass FromResult am analogsten und immer noch am besten abschneidet, wenn Sie einen Wert zurückgeben müssen.Ich weiß, dass dies ein alter Thread ist, und vielleicht hat dies nicht für alle Verwendungen den richtigen Effekt, aber das Folgende ist so nah wie möglich daran, einfach eine NotImplementedException auslösen zu können, wenn ich noch keine Methode implementiert habe. ohne die Methodensignatur zu ändern. Wenn es problematisch ist, würde ich mich freuen, es zu wissen, aber es ist mir kaum wichtig: Ich benutze es sowieso nur während der Entwicklung, daher ist es nicht so wichtig, wie es funktioniert. Trotzdem würde ich mich freuen zu hören, warum es eine schlechte Idee ist, wenn es so ist.
Hier ist der Typ, den ich hinzugefügt habe, um dies zu ermöglichen.
quelle
Nur als Update für Stephens Antwort müssen Sie die
TaskConstants
Klasse nicht mehr schreiben , da es eine neue Hilfsmethode gibt:quelle
Falls Sie bereits eine Verknüpfung zu Reactive Extension herstellen, können Sie außerdem Folgendes tun:
Reaktiv und asynchron / warten sind an und für sich erstaunlich, aber sie spielen auch gut zusammen.
Eingeschlossen sind:
quelle
Es könnte cs1998 unten auftreten.
Dann können Sie unten reformieren.
quelle
Sie könnten dies versuchen:
quelle
Versuche dies:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS1998:Await.Warning")]
Siehe: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.suppressmessageattribute?view=netframework-4.7.2
quelle
Wenn Sie nichts zu erwarten haben, geben Sie Task.FromResult zurück
quelle
Hier sind einige Alternativen, die von Ihrer Methodensignatur abhängen.
quelle
quelle
Sie können das asynchrone Schlüsselwort aus der Methode entfernen und es einfach Task zurückgeben lassen.
quelle