Der Fluss, der erwartet in .NET 4.5 und Async CTP 4.0 enthält, kann aus verschiedenen Gründen stecken, z. da der Remote-Client nicht geantwortet hat. Natürlich ist WaitForAny, wenn wir auch auf eine Timeout-Aufgabe warten, eine offensichtliche Lösung für die Wiederherstellung des High-Level-Flusses. Dies löst jedoch nicht alle möglichen Probleme.
Ich habe folgende Fragen:
Was passiert mit dem Kontext von await , das niemals zurückgegeben wird? Ich verstehe, dass dies zu Speicherverlust führen wird. Habe ich recht?
Wie kann ich entweder im Debugger oder über die entsprechende API prüfen, wie viele " aware" "" "in der Anwendung vorhanden sind?
Ist es möglich, sie global aufzuzählen?
Wenn 3. korrekt ist, ist es möglich, die Aufgaben für diese * abzuwarten * s (d. h. aufzuräumen) zu stornieren?
Hinweis: In Frage 4 werde ich nicht nach Abbruchelementen gefragt, die bei der expliziten Aufgabenerstellung verwendet werden sollen. Ich meine den Fall, als die Aufgabe indirekt erstellt wurde:
%Vor%Motivation für diese Frage:
1 Was passiert mit dem Kontext von "Warten", der niemals wiederkehrt?
Ich glaube, das führt zu einem Speicherverlust (wenn Sie eine E / A-Operation ausführen). Am besten vervollständigen Sie immer Ihre await
s (und das bedeutet Immer haben Ihre Task
Methoden früher oder später zurückzukehren.)
Aktualisierung von svicks Kommentar: Es gibt Situationen , wo dies nicht einen Speicherverlust verursachen würde.
2 Wie kann ich entweder im Debugger oder über die entsprechende API prüfen, wie viele hängende "Avatare" in der Anwendung existieren?
Ich bin mir nicht sicher, ob es einen einfachen Weg dafür gibt. Ich glaube, es sollte möglich sein, ein Debugger-Plugin zu schreiben, das SoS verwendet, um existierende Heap-Objekte zu finden, die mit dem Muster der vom Compiler generierten asynchronen Zustandsautomaten übereinstimmen.
Aber das ist eine Menge Arbeit für wenig Nutzen.
3 Ist es möglich, sie global aufzuzählen?
Nicht mit den normalen APIs.
Wenn 3 korrekt ist, ist es möglich, die Löschung der Aufgaben für diese zu erzwingen (d. h. aufzuräumen)?
Selbst wenn Sie sie zur Laufzeit aufzählen könnten (z. B. über die Profiling-API), können Sie die Löschung für eine Aufgabe nicht erzwingen. Stornierung ist kooperativ.
Der richtige Weg, um damit fertig zu werden, ist die Standardunterdrückung. Das Dokument Aufgabebasiertes asynchrones Muster gibt Richtlinien für abbrechbare Methoden async
vor.
Auf der niedrigsten Ebene: Viele async
APIs in der BCL nehmen ein optionales async
.
Auf einer mittleren Ebene: Es ist üblich, dass eine CancellationToken
-Methode eine optionale async
verwendet und sie einfach an andere CancellationToken
-Methoden weiterleitet.
Auf der höchsten Ebene: Es ist einfach zu erstellen ein async
, das danach ausgelöst wird eine bestimmte Zeit.
Über die Fragen 2 und 3 habe ich keine wirkliche Antwort.
Aufgaben, die nie wiederkehren, sind selten eine gute Sache. Um dies zu vermeiden und Punkt 4 zu beantworten, können Aufgaben abgebrochen werden.
Sie müssen ein Cancellingtoken erstellen, das Sie an die Aufgabe übergeben. Die Aufgabe ist selbst dafür verantwortlich, nach dem Status des Abbruch-Tokens Ausschau zu halten und eine Ausnahme auszulösen, wenn sie abgebrochen wird. (Mehrere Aufgaben können gleichzeitig mit demselben Token abgebrochen werden.)
Dieser Artikel in MSDN zeigt Ihnen dies.
Tags und Links c# .net-4.5 asynchronous error-handling async-ctp