Partilhar via


Destrua fios

Para terminar a execução do thread, normalmente utiliza-se o modelo de cancelamento cooperativo. No entanto, por vezes não é possível parar um thread cooperativamente, porque corre código de terceiros não concebido para cancelamento cooperativo. Nas aplicações .NET Framework, pode usar o Thread.Abort método para terminar forçosamente um thread gerido. Quando chamas Abort, o Common Language Runtime lança a ThreadAbortException no thread de destino, que o thread de destino pode capturar. (No entanto, o runtime do .NET Framework relança sempre automaticamente a exceção após o catch bloco.) Para mais informações, veja Thread.Abort.

O método Thread.Abort lança uma exceção PlatformNotSupportedException em tempo de execução no .NET Core e no .NET 5 e versões posteriores. A partir do .NET 5, também está marcado como obsoleto (SYSLIB0006), por isso chamá-lo gera um aviso em tempo de compilação. Se precisar de terminar à força a execução de código de terceiros em implementações modernas de .NET, execute-o no processo separado e use Process.Kill.

Observação

  • Quando você chama Thread.Abort para anular um thread diferente do thread atual, você não sabe qual código foi executado ou falhou em executar quando o ThreadAbortException é lançado. Também não pode ter a certeza do estado da sua aplicação ou de qualquer estado da aplicação e do utilizador que ela seja responsável por preservar. Por exemplo, a chamada Thread.Abort pode impedir a execução de construtores estáticos ou a liberação de recursos gerenciados ou não gerenciados.
  • Se uma thread estiver a executar código não gerido quando o seu Abort método é chamado, o tempo de execução marca-o ThreadState.AbortRequested. A exceção é lançada quando o thread regressa ao código gerido.

Uma vez que um thread é abortado, não pode ser reiniciado.

O método Abort não faz com que a thread aborte imediatamente, porque a thread alvo pode apanhar o ThreadAbortException e executar quantidades arbitrárias de código num bloco finally. Podes ligar Thread.Join se precisares de esperar até o tópico terminar. Thread.Join é uma chamada de bloqueio que só retorna até que o thread tenha realmente parado de executar ou que tenha passado um intervalo opcional de timeout. O thread abortado pode chamar o ResetAbort método ou realizar processamento ilimitado num finally bloco, por isso, se não especificar um timeout, a espera não tem garantia de terminar.

Threads que estão à espera de uma chamada para o método Thread.Join podem ser interrompidos por outros threads que chamam Thread.Interrupt.

Tratamento do ThreadAbortException

Se esperar que a sua thread seja abortada, seja como resultado de chamar Abort a partir do seu próprio código ou devido ao descarregamento de um domínio de aplicação onde a thread está a correr (AppDomain.Unload usa Thread.Abort para terminar threads), a sua thread deve tratar ThreadAbortException e realizar qualquer processamento final numa cláusula finally, como mostrado no código seguinte.

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.  

O seu código de limpeza deve estar na cláusula catch ou na cláusula finally, porque a ThreadAbortException é relançada pelo sistema no final da cláusula finally, ou no final da cláusula catch se não houver cláusula finally.

Pode impedir que o sistema volte a lançar a exceção chamando o Thread.ResetAbort método. No entanto, só deve proceder desta forma se o seu próprio código tiver causado o ThreadAbortException.

Consulte também