Ihr Vorschlag scheint auf den ersten Blick wie ein Missbrauch des Finalizers zu sein. Wie bereits erwähnt, sind Finalizer typischerweise für die Bereinigung nicht verwalteter Ressourcen zuständig. Noch wichtiger ist, dass Finalizer nicht Teil der Vertragsgestaltung eines Objekts sein sollten. Sie existieren nur zu dem Zweck, als Backstop für fehlerhaften Code zu dienen, d. H. Um Ressourcen zu bereinigen, wenn der Client-Code dies nicht explizit getan hat (z. B. durch Aufruf von IDisposable.Dispose()
).
Also die erste Sache, die ich betrachten würde ist, wie nicht-buggy Code sollte mit Ihrer Klasse interagieren. Gibt es tatsächlich eine IDisposable
Implementierung? Wenn nicht, dann sollte es auch keinen Finalizer geben. Fühlst du dich stark, brauchst du einen Finalizer? Dann sollte Ihre Klasse IDisposable
(oder ein Äquivalent) implementieren, damit der korrekte Code das Objekt effizient bereinigen kann.
Jetzt ist die zweite Sache zu betrachten, ob diese Aufgabe überhaupt abgebrochen werden muss. Was hoffst du zu erreichen, indem du die Aufgabe annullierst? Erwarten Sie, die Aufgabe in einem Szenario anderen abzubrechen, als den Prozess zu beenden? Wie ist die Aufgabe selbst implementiert? Starten Sie die Aufgabe überhaupt irgendwo? Dies sind alles Fragen, die in Ihrer Frage nicht behandelt werden, so dass niemand sie direkt ansprechen kann.
Ich werde jedoch darauf hinweisen, dass die Standardimplementierung für das Task
-Objekt unter der Annahme, dass Sie die Start()
-Methode aufrufen, den Code mit einem Thread-Pool-Thread ausführen soll. Thread-Pool-Threads sind alle Hintergrund-Threads, und diese Threads werden automatisch beendet, wenn alle Vordergrund-Threads beendet wurden, wodurch der Prozess selbst normal beendet werden kann.
Also, wenn alles, was Sie sind besorgt über den Zustand der Aufgabe ist es, wenn der Prozess beendet, und Sie die Standardimplementierung für die Aufgabe verwenden, und die Aufgabe sicher jederzeit unterbrochen werden, ohne korrumpieren Daten oder das Verlassen eines temporären Zustands (zB eine temporäre Datei, die gelöscht werden sollte, wenn die Aufgabe abgeschlossen ist), dann denke ich nicht, dass Sie die Aufgabe explizit abbrechen müssen.
Auf der anderen Seite, wenn es einen Grund gibt, die Aufgabe explizit abzubrechen, ist der richtige Weg, um einen Mechanismus (z. B. implementieren IDisposable
oder etwas expliziter), dass der Client-Code verwenden können, explizit zu benachrichtigen Objekt, dass es nicht mehr benötigt wird und sollte aufräumen. Wenn der Client-Code diesen Mechanismus aufruft, können Sie die Aufgabe abbrechen.
In diesem Fall möchten Sie möglicherweise einen Finalizer implementieren, aber Sie müssen wissen, dass dieser Finalizer bei korrektem Clientcode nie aufgerufen wird. Es dient nur zum Schutz vor schlechtem Verhalten. Es ist auch sehr wichtig zu verstehen, dass es überhaupt keine Garantie dafür gibt, dass der Finalizer jemals aufgerufen wird, selbst für Code mit schlechtem Verhalten, und das wahrscheinlichste Szenario, dass er nicht aufgerufen wird, ist tatsächlich, wenn der Prozess beendet wird.
Schließlich, wenn Sie feststellen, dass ein Finalizer tatsächlich erforderlich ist, fordere ich Sie auf, die SafeHandle
Klasse zu betrachten. Dies ist eine .NET-Klasse, die Sie als Basisklasse für ein Hilfsobjekt verwenden können, das den Wegwerfcharakter Ihres Aufgabenobjekts abstrahiert. Auf diese Weise muss Ihr eigenes Objekt keinen Finalizer selbst implementieren. stattdessen wird die SafeHandle
Unterklasse, die Sie implementieren, automatisch diese Notwendigkeit adressieren.
Ehh, wenn Sie die Anwendung dann töten, würde das nicht die Aufgabe töten? http://stackoverflow.com/questions/1687677/does-closing-the-application-stops-all-active-backgroundworkers –
Finalizer sind für die Freigabe nicht verwalteter Ressourcen. Sie sollten nicht mit verwalteten Ressourcen im Finalizer interagieren. – Servy
Sie sollten "viewModelA" Disposable machen und Sie sollten die Aufgabe dort abbrechen. –