Ich versuche, einen ThreadManager für meine C # -Anwendung zu schreiben. Ich erstelle mehrere Threads:
Ein Thread für meinen Texter.
Ein Thread, der einige Statistiken überwacht.
Mehrere Threads, um eine große Reihe von Berechnungen durchzuführen (bis zu 4 Threads pro Kern und ich führe meine App auf einem 2x Quad-Core-Server aus).
Meine Anwendung läuft normalerweise immer bis zu 24 Stunden, so dass alle Threads zu Beginn erstellt werden und während der gesamten Laufzeit der App bestehen bleiben.
Ich möchte einen einzigen Ort haben, an dem ich alle meine Schritte "registriere" und wenn die Anwendung heruntergefahren wird, rufe ich einfach eine Methode auf und sie durchläuft alle registrierten Threads und schließt sie.
Zu diesem Zweck habe ich folgende Klasse entwickelt:
%Vor%Ich möchte sicherstellen, dass alle meine Threads getötet werden, so dass die Anwendung ordnungsgemäß geschlossen werden kann, und das Herunterfahren in der Mitte einiger Berechnungen ist auch in Ordnung. Sollte mir hier etwas bekannt sein? Ist dieser Ansatz angesichts meiner Situation gut?
Wenn Sie die Threads auf Hintergrundthreads setzen, werden sie beim Herunterfahren der Anwendung gelöscht.
%Vor%Wenn Sie möchten, dass die Threads vor dem Herunterfahren beendet werden, ist dies natürlich nicht die gewünschte Lösung.
Das Abbrechen von Threads ist das, was Sie tun wenn alles andere fehlschlägt . Es ist eine gefährliche Sache, die Sie nur als letzten Ausweg tun sollten. Die richtige Vorgehensweise besteht darin, die Threading-Logik so zu gestalten, dass jeder Worker-Thread schnell und korrekt reagiert, wenn der Haupt-Thread den Befehl zum Herunterfahren gibt.
Zufälligerweise ist dies das Thema meines Blogs diese Woche.
Was ist, wenn AddThread aufgerufen wird, während Ihr Shutdown ausgeführt wird?
Nach Beendigung des Herunterfahrens fügt der Thread, der in AddThread wartet, der Sammlung einen neuen Thread hinzu. Dies könnte dazu führen, dass Sie in Ihrer App hängen bleiben.
Fügen Sie ein Bool-Flag hinzu, das Sie nur in Shutdown festgelegt haben, um sich davor zu schützen.
%Vor%Sie sollten auch keine statischen Mitglieder verwenden - dafür gibt es keinen Grund, da Sie Ihre Singleton-Instanz haben.
.Abort () bricht Threads, die im nicht verwalteten Speicherbereich blockieren, nicht ab. Wenn Sie das tun, müssen Sie einen anderen Mechanismus verwenden.
Das einzige Problem, das ich kenne, ist dieses: Ссылка
Aber ich würde vermeiden, auf ein Design wie dieses zurückgreifen zu müssen. Sie könnten jeden Ihrer Threads dazu zwingen, einige Flags regelmäßig zu überprüfen, dass es Zeit für das Herunterfahren ist, und wenn Sie herunterfahren, setzen Sie dieses Flag und warten Sie, bis alle Threads beendet sind (mit Join ()). Es fühlt sich ein bisschen mehr wie kontrolliertes Herunterfahren an.
Wenn Sie den Status des Arbeitsthreads nicht interessiert, können Sie _thread durchlaufen und abbrechen:
%Vor%In Ihrem Fall können Sie wahrscheinlich alle abbrechen und herunterfahren, da sie nur Berechnungen durchführen. Wenn Sie jedoch auf eine Datenbankschreiboperation warten müssen oder eine nicht verwaltete Ressource schließen müssen, müssen Sie entweder die ThreadAbortException abfangen oder den Threads signalisieren, dass sie sich selbst töten.
Sie möchten eine verzögerte Thread-Annullierung, was im Grunde bedeutet, dass die Threads sich selbst beenden, im Gegensatz zu einem Thread-Manager, der Threads asynchron abbricht, was viel schlechter definiert und gefährlich ist.
Wenn Sie die Thread-Löschung eleganter handhaben wollten als die sofortige Beendigung, können Sie Signal-Handler verwenden, die durch Ereignisse außerhalb des Threads ausgelöst werden - vielleicht von Ihrem Thread-Manager.
Tags und Links c# multithreading