Zerstören von Threads
Um die Ausführung eines Threads zu beenden, verwenden Sie im Normalfall die kooperative Abbruchmethode. Manchmal ist es nicht möglich, einen Thread kooperativ zu beenden, weil darin Drittanbietercode ausgeführt wird, der für einen kooperativen Abbruch nicht geeignet ist. In .NET Framework-Apps können Sie die Thread.Abort-Methode verwenden, um das Beenden eines verwalteten Threads zu erzwingen. Beim Aufruf von Abort löst die Common Language Runtime eine ThreadAbortException im Zielthread aus, die der Zielthread abfangen kann. (Die .NET Framework-Runtime löst die Ausnahme nach dem catch
-Block jedoch immer automatisch erneut aus.) Weitere Informationen finden Sie unter Thread.Abort.
Die Thread.Abort-Methode wird in .NET 5 und höheren Versionen (einschließlich .NET Core) nicht unterstützt. Wenn Sie die Beendigung der Ausführung von Drittanbietercode in .NET 5 oder einer höheren Version erzwingen müssen, führen Sie den Code in einem separaten Prozess aus, und verwenden Sie Process.Kill.
Hinweis
- Wenn Sie Thread.Abort aufrufen, um einen anderen Thread als den aktuellen Thread zu beenden, wissen Sie nicht, welcher Code ausgeführt wurde oder nicht ausgeführt werden konnte, wenn die ThreadAbortException ausgelöst wird. Sie können sich auch nicht sicher sein, welchen Zustand Ihre Anwendung oder ein Anwendungs- und Benutzerstatus hat, für den sie verantwortlich ist. Beispielsweise kann der Aufruf von Thread.Abort die Ausführung statischer Konstruktoren oder die Freigabe verwalteter oder nicht verwalteter Ressourcen verhindern.
- Wenn ein Thread nicht verwalteten Code ausführt, wenn seine Abort-Methode aufgerufen wird, markiert die Runtime ihn mit ThreadState.AbortRequested. Die Ausnahme wird ausgelöst, wenn der Thread zu verwaltetem Code zurückkehrt.
Sobald ein Thread abgebrochen wird, kann er nicht erneut gestartet werden.
Die Abort-Methode bewirkt keinen sofortigen Abbruch des Threads, da der Zielthread die ThreadAbortException abfangen und beliebige Mengen von Code in einem finally
-Block ausführen kann. Sie können Thread.Join aufrufen, wenn Sie warten müssen, bis der Thread beendet ist. Thread.Join ist ein blockierender Aufruf, von dem keine Rückgabe erfolgt, bis die Ausführung des Threads tatsächlich beendet wurde oder ein optionales Timeoutintervall verstrichen ist. Der abgebrochene Thread könnte die ResetAbort-Methode aufrufen oder unbegrenzte Verarbeitung in einem finally
-Block ausführen – wenn Sie also keinen Timeout angeben, ist nicht garantiert, dass das Warten endet.
Threads, die auf einen Aufruf der Thread.Join-Methode warten, können von anderen Threads unterbrochen werden, die Thread.Interrupt aufrufen.
Behandeln von ThreadAbortException
Wenn Sie davon ausgehen, dass Ihr Thread entweder als Folge eines Aufrufs von Abort aus Ihrem eigenen Code oder als Ergebnis des Entladens einer Anwendungsdomäne, in der der Thread ausgeführt wird (AppDomain.Unload verwendet Thread.Abort, um Threads zu beenden), abgebrochen wird, muss Ihr Thread die ThreadAbortException behandeln und jegliche endgültige Verarbeitung in einer finally
-Klausel ausführen, wie im folgenden Code gezeigt.
Try
' Code that is executing when the thread is aborted.
Catch ex As ThreadAbortException
' Clean-up code can go here.
' If there is no Finally clause, ThreadAbortException is
' re-thrown by the system at the end of the Catch clause.
Finally
' Clean-up code can go here.
End Try
' Do not put clean-up code here, because the exception
' is rethrown at the end of the Finally clause.
try
{
// Code that is executing when the thread is aborted.
}
catch (ThreadAbortException ex)
{
// Clean-up code can go here.
// If there is no Finally clause, ThreadAbortException is
// re-thrown by the system at the end of the Catch clause.
}
// Do not put clean-up code here, because the exception
// is rethrown at the end of the Finally clause.
Ihr Bereinigungscode muss sich in der catch
- oder finally
-Klausel befinden, da eine ThreadAbortException erneut am Ende der finally
-Klausel bzw. am Ende der catch
-Klausel vom System ausgelöst wird, wenn es keine finally
-Klausel gibt.
Sie können das erneute Auslösen der Ausnahme durch das System mit Aufrufen der Thread.ResetAbort-Methode verhindern. Allerdings sollten Sie dies nur tun, wenn Ihr eigener Code die ThreadAbortException verursacht hat.