Es scheint, dass Block schließlich nicht ausgeführt wird, wenn es anderen als Hauptthreadcode ausführt. Ist es möglich, die Ausführung in diesem Fall zu erzwingen?
Umgebung: VS 2010, .Net Framework 4.0.3
%Vor%Aktualisierung:
Ich fand Erwähnungen und Erklärungen zu diesem Fall in MSDN:
ThreadAbortException-Klasse Ссылка
Wenn ein Aufruf an die Abort-Methode erfolgt, um einen Thread zu zerstören, wird der Common Language Runtime löst eine ThreadAbortException aus. ThreadAbortException ist eine spezielle Ausnahme, die abgefangen werden kann, aber es wird automatisch am Ende des Catch-Blocks wieder ausgelöst. Wann Diese Ausnahme wird ausgelöst. Die Laufzeitumgebung führt alle finally-Blöcke aus bevor der Thread beendet wird . Weil der Thread ein unbegrenztes tun kann Berechnung in den endgültig blockiert oder Thread.ResetAbort aufrufen, um abzubrechen Beim Abbruch gibt es keine Garantie, dass der Thread jemals enden wird . Ob Wenn Sie warten möchten, bis der abgebrochene Thread beendet ist, können Sie die Thread.Join-Methode. Join ist ein blockierender Aufruf, der erst zurückkehrt Der Thread stoppt die Ausführung tatsächlich.
Hinweis:
Wenn die Common Language Runtime (CLR) Hintergrundthreads nach beendet Alle Vordergrund-Threads in einer verwalteten ausführbaren Datei sind beendet, dies jedoch nicht Verwenden Sie Thread.Abort. Daher können Sie ThreadAbortException nicht verwenden erkennen, wenn Hintergrund-Threads von der CLR beendet werden.
Vordergrund- und Hintergrund-Threads Ссылка
Wenn die Laufzeit einen Hintergrund-Thread stoppt, weil der Prozess heruntergefahren wird, wird keine Ausnahme im Thread ausgelöst. Wenn Threads jedoch angehalten werden, weil die AppDomain.Unload-Methode die Anwendungsdomäne entfernt, wird eine ThreadAbortException sowohl im Vordergrund als auch im Hintergrund ausgelöst.
Warum verwendet CLR am Ende der Anwendung nicht die AppDomain.Unload-Methode zum Entladen der Anwendungsdomäne vor dem Ende (Kill) des Hauptprozesses? Weil Ссылка :
Wenn ein Thread Unload aufruft, wird die Zieldomäne zum Entladen markiert. Der dedizierte Thread versucht, die Domäne und alle darin enthaltenen Threads zu entladen Die Domain wird abgebrochen. Wenn beispielsweise ein Thread nicht abbricht weil es nicht verwalteten Code ausführt oder weil es a ausführt endlich blockieren, dann nach einer gewissen Zeit a CannotUnloadAppDomainException wird im ursprünglichen Thread ausgelöst Unload genannt. Wenn der Thread, der schließlich nicht abgebrochen werden konnte endet, wird die Zieldomäne nicht entladen. Daher im .NET Framework Für die Version 2.0-Domäne wird nicht garantiert, zu entladen, da dies möglicherweise nicht der Fall ist möglich sein, ausführende Threads zu beenden.
Fazit: In einigen Fällen muss ich überlegen, ob mein Code im Hintergrund- oder Vordergrund-Thread ausgeführt wird. Ist es möglich, dass mein Code nicht beendet wird, bevor der Anwendungs-Haupt-Thread alle Arbeit beendet?
Ihr Code wird in einem Hintergrundthread ausgeführt. Wenn Sie AutoResetEvent
festlegen, wird Ihr einzelner Vordergrund-Thread beendet (wenn Sie das Ende der Main
-Methode erreichen), und der Prozess wird "sofort" abgebrochen.
Tatsächlich glaube ich, dass es wahrscheinlich ist, dass Ihr finally
block ausgeführt wird, aber da Sie als erstes zwei Sekunden lang schlafen, wird der Prozess beendet, bevor er zu Ihrem WriteLine
gelangt. ruf an.
Wenn Ihre Main
-Methode noch immer ausgeführt wird oder ein anderer Vordergrund-Thread den Prozess am Leben erhält, sehen Sie Ihren finally
-Block als normal. Dies ist nicht wirklich eine Frage von "endlich auf anderen Threads" - es ist eine Frage von "der Prozess bleibt nur am Leben, während es Vordergrund Threads gibt."
Sie können verhindern, dass die Hauptmethode beendet wird, bis die finally ausgeführt wurde. Es gibt viele mögliche Ansätze.
Sie können die Synchronisierung verwenden, um dies zu erreichen. Zum Beispiel mit einem ResetEvent, ähnlich dem, was Sie bereits tun, oder explizit einen Thread erstellen und sich diesem anschließen.
Sie könnten am Ende der Main
-Methode nur einen einfachen Sleep oder eine Readline ausführen:
Dann kann der Benutzer steuern, wann das Programm beendet wird.
Tags und Links .net c# multithreading try-catch-finally