Niszczenie wątków

Aby zakończyć wykonywanie wątku, zazwyczaj używasz modelu anulowania współpracy. Jednak czasami nie można zatrzymać wątku współpracy, ponieważ uruchamia kod innej firmy, który nie jest przeznaczony do anulowania współpracy. W aplikacjach .NET Framework można użyć Thread.Abort metody , aby wymuśnić zakończenie zarządzanego wątku. Po wywołaniu Abortwywołania środowisko uruchomieniowe języka wspólnego zgłasza element ThreadAbortException w wątku docelowym, który może przechwytywać wątek docelowy. (Jednak środowisko uruchomieniowe programu .NET Framework zawsze automatycznie ponownie zwraca wyjątek po catch bloku). Aby uzyskać więcej informacji, zobacz Thread.Abort.

Metoda nie jest obsługiwanaThread.Abort na platformie .NET 5 (w tym .NET Core) i nowszych wersjach. Jeśli musisz zakończyć wykonywanie kodu innej firmy przymusowo na platformie .NET 5+, uruchom go w osobnym procesie i użyj polecenia Process.Kill.

Uwaga

  • W przypadku wywołania Thread.Abort metody przerwania wątku innego niż bieżący wątek nie wiadomo, jaki kod został wykonany lub nie można wykonać go ThreadAbortException po wyświetleniu. Nie można również mieć pewności co do stanu aplikacji ani jakiejkolwiek aplikacji i stanu użytkownika, który jest odpowiedzialny za zachowanie. Na przykład wywołanie Thread.Abort może uniemożliwić wykonywanie konstruktorów statycznych lub wydanie zarządzanych lub niezarządzanych zasobów.
  • Jeśli wątek wykonuje kod niezarządzany, gdy jest wywoływana jego Abort metoda, środowisko uruchomieniowe oznacza go ThreadState.AbortRequested. Wyjątek jest zgłaszany, gdy wątek powróci do kodu zarządzanego.

Po przerwaniu wątku nie można go ponownie uruchomić.

Metoda Abort nie powoduje natychmiastowego przerwania wątku, ponieważ wątek docelowy może przechwytywać ThreadAbortException i wykonywać dowolne ilości kodu w finally bloku. Możesz wywołać metodę Thread.Join , jeśli musisz poczekać na zakończenie wątku. Thread.Join jest wywołaniem blokującym, które nie zwraca się, dopóki wątek rzeczywiście przestał wykonywać lub opcjonalny interwał limitu czasu upłynął. Przerwany wątek może wywołać metodę ResetAbort lub wykonać niezwiązane przetwarzanie w finally bloku, więc jeśli nie określisz limitu czasu, oczekiwanie nie będzie gwarantowane do końca.

Wątki oczekujące na wywołanie Thread.Join metody mogą zostać przerwane przez inne wątki wywołujące metodę Thread.Interrupt.

Obsługa elementu ThreadAbortException

Jeśli oczekujesz, że wątek zostanie przerwany, albo w wyniku wywołania Abort z własnego kodu lub w wyniku zwolnienia domeny aplikacji, w której działa wątek (AppDomain.Unload używa Thread.Abort do zakończenia wątków), wątek musi obsłużyć ThreadAbortException i wykonać końcowe przetwarzanie w finally klauzuli, jak pokazano w poniższym kodzie.

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.  

Kod czyszczenia musi znajdować się w catch klauzuli lub finally klauzuli, ponieważ ThreadAbortException element jest ponownie wprowadzany przez system na końcu klauzuli lub na końcu catchfinally klauzuli , jeśli nie finally ma klauzuli.

Można uniemożliwić systemowi ponowne wywołanie wyjątku Thread.ResetAbort przez wywołanie metody . Jednak należy to zrobić tylko wtedy, gdy twój własny kod spowodował .ThreadAbortException

Zobacz też