Überlegungen zum Warten auf eine Aufgabe in einer asynchronen Methode

8

Ich arbeite an einem Web-API-Projekt, das den verwalteten Cache-Dienst von Azure verwendet, um Datenbankergebnisse im Arbeitsspeicher zwischenzuspeichern, um die Antwortzeiten zu verbessern und doppelten Datenverkehr zur Datenbank zu verringern. Beim Versuch, ein neues Objekt in den Cache zu stellen, wird gelegentlich eine cache-spezifische Ausnahme mit dem Code DataCacheErrorCode.RetryLater ausgelöst. Natürlich, um es später erneut zu versuchen, ohne diese Methode blockieren zu müssen, habe ich async und await Task.Delay gemacht, um es kurze Zeit später erneut zu versuchen. Zuvor hatte ein Entwickler eine Thread.Sleep fest programmiert, die die Anwendungsleistung wirklich beeinträchtigte.

Die Methodensignatur sieht jetzt ähnlich aus:

%Vor%

Nach dieser Änderung bekomme ich ca. 75 Compilerwarnungen von allen anderen Stellen in der Anwendung, die die ehemals synchrone Version von Put aufgerufen haben, was folgendes anzeigt:

  

Da dieser Aufruf nicht erwartet wird, wird die Ausführung der aktuellen Methode fortgesetzt, bevor der Aufruf beendet wird. Ziehen Sie in Erwägung, den Operator 'abwarten' auf das Ergebnis des Aufrufs anzuwenden.

Da in diesem Fall Put nichts zurückgibt, ist es für mich sinnvoll, diese Operation fire-and-forget zuzulassen, da ich keinen Grund sehe, die Ausführung von zu blockieren die Methode, die es aufgerufen hat. Ich frage mich nur, ob es irgendwelche Gefahren oder Fallstricke dafür gibt, eine Menge dieser Feuer-und-Vergessen Task s im Hintergrund laufen zu lassen, da Put ziemlich oft aufgerufen werden kann. Oder sollte ich sowieso warten, da ich 99% der Zeit nicht den Wiederholungsfehler bekomme und der Task wird fast sofort fertig sein. Ich möchte nur sicherstellen, dass ich keine Strafen für zu viele Threads (oder so ähnlich) bekomme.

    
Jesse Carter 17.11.2014, 17:28
quelle

4 Antworten

6

Wenn es eine Chance gibt, dass Put aus irgendeinem Grund eine andere Ausnahme auslöst und Sie await Put nicht jedes Mal verwenden, wenn Sie ein Objekt in den Cache einfügen, werden die Ausnahmen innerhalb der hat Task zurückgegeben, was nicht erwartet wird. Wenn Sie .NET 4.0 verwenden, wird diese Ausnahme innerhalb des Finalizers dieses Task. erneut ausgelöst. Wenn Sie .NET 4.5 verwenden, wird es einfach ignoriert (und das ist möglicherweise nicht wünschenswert).

  

Ich möchte sicherstellen, dass ich keine Strafen dafür erleide   viele Threads oder so ähnlich.

Ich sage das nur, um die Dinge klarzustellen. Wenn Sie Task.Delay verwenden, werden keine neuen Threads gedreht. A Task ist nicht immer gleich einem neuen Thread, der gesponnen wird. Speziell hier verwendet Task.Delay intern Timer , also gibt es keine Thread-Gemeinkosten (außer für den Thread, der gerade verzögert wird, wenn Sie await verwenden).

    
Yuval Itzchakov 17.11.2014, 17:36
quelle
2

Die Warnung sagt Ihnen, dass Sie Feuer bekommen und das Verhalten an einem Ort vergessen, an dem Sie möglicherweise nicht schießen und vergessen möchten. Wenn Sie wirklich feuern und vergessen möchten und kein Problem mehr haben, ohne jemals zu wissen, wann die Operation abgeschlossen ist oder ob sie erfolgreich abgeschlossen wurde, können Sie die Warnung ignorieren.

    
Servy 17.11.2014 17:31
quelle
1

Ein negatives Ergebnis beim Freigeben einer Task, die nicht ausgeführt werden soll, sind die Compilerwarnungen selbst. 75 Compilerwarnungen sind an und für sich ein Problem, und sie verbergen echte Warnungen.

Wenn Sie dem Compiler signalisieren wollen, dass Sie absichtlich nichts mit dem Ergebnis der Aufgabe machen, können Sie eine einfache Erweiterungsmethode verwenden, die nichts tut, aber den Wunsch des Compilers nach Explizitheit erfüllt .

%Vor%

Jetzt können Sie

anrufen %Vor%

ohne Compiler-Warnungen.

Ссылка

    
Avner Shahar-Kashtan 09.05.2017 08:35
quelle
0

Empfohlener ASP.NET-Weg ist

%Vor%

BTW Nicht fangen / erneut werfen auf Thread anders als ASP.NET-Thread kann dazu führen, dass Server-Prozess abgestürzt / neu gestartet wird

    
Yuri 09.05.2017 08:20
quelle