Destroy threads

To terminate the execution of the thread, you usually use the cooperative cancellation model. However, sometimes it's not possible to stop a thread cooperatively, because it runs third-party code not designed for cooperative cancellation. In .NET Framework apps, you can use the Thread.Abort method to terminate a managed thread forcibly. When you call Abort, the Common Language Runtime throws a ThreadAbortException in the target thread, which the target thread can catch. (However, the .NET Framework runtime always automatically rethrows the exception after the catch block.) For more information, see Thread.Abort.

The Thread.Abort method is not supported in .NET 5 (including .NET Core) and later versions. If you need to terminate the execution of third-party code forcibly in .NET 5+, run it in the separate process and use Process.Kill.

Note

  • When you call Thread.Abort to abort a thread other than the current thread, you don't know what code has executed or failed to execute when the ThreadAbortException is thrown. You also cannot be certain of the state of your application or any application and user state that it's responsible for preserving. For example, calling Thread.Abort may prevent the execution of static constructors or the release of managed or unmanaged resources.
  • If a thread is executing unmanaged code when its Abort method is called, the runtime marks it ThreadState.AbortRequested. The exception is thrown when the thread returns to managed code.

Once a thread is aborted, it cannot be restarted.

The Abort method does not cause the thread to abort immediately, because the target thread can catch the ThreadAbortException and execute arbitrary amounts of code in a finally block. You can call Thread.Join if you need to wait until the thread has ended. Thread.Join is a blocking call that does not return until the thread has actually stopped executing or an optional timeout interval has elapsed. The aborted thread could call the ResetAbort method or perform unbounded processing in a finally block, so if you do not specify a timeout, the wait is not guaranteed to end.

Threads that are waiting on a call to the Thread.Join method can be interrupted by other threads that call Thread.Interrupt.

Handling ThreadAbortException

If you expect your thread to be aborted, either as a result of calling Abort from your own code or as a result of unloading an application domain in which the thread is running (AppDomain.Unload uses Thread.Abort to terminate threads), your thread must handle the ThreadAbortException and perform any final processing in a finally clause, as shown in the following code.

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.  

Your clean-up code must be in the catch clause or the finally clause, because a ThreadAbortException is rethrown by the system at the end of the finally clause, or at the end of the catch clause if there is no finally clause.

You can prevent the system from rethrowing the exception by calling the Thread.ResetAbort method. However, you should do this only if your own code caused the ThreadAbortException.

See also