Matando um encadeamento do .NET

Eu criei um segmento executando um determinado método. Mas às vezes eu gostaria de matar o tópico mesmo se ele ainda estiver funcionando. Como posso fazer isso? Eu tentei Thread.Abort (), mas ele mostra uma checkbox de mensagem dizendo “Tópico abortado”. O que devo fazer?

Não chame Thread.Abort() !

Thread.Abort é perigoso. Em vez disso, você deve cooperar com o encadeamento para que ele possa ser encerrado de forma pacífica. O encadeamento precisa ser projetado para que possa ser dito para se matar, por exemplo, com um sinalizador keepGoing booleano que você definiu como false quando quiser que o encadeamento pare. O fio teria então algo como

 while (keepGoing) { /* Do work. */ } 

Se o thread pode bloquear em um modo de Sleep ou Wait seguida, você pode Thread.Interrupt() -lo dessas funções chamando Thread.Interrupt() . O encadeamento deve então ser preparado para manipular um ThreadInterruptedException :

 try { while (keepGoing) { /* Do work. */ } } catch (ThreadInterruptedException exception) { /* Clean up. */ } 

Você deve realmente chamar Abort () apenas como último recurso. Você pode usar uma variável para sincronizar este segmento:

 volatile bool shutdown = false; void RunThread() { while (!shutdown) { ... } } void StopThread() { shutdown = true; } 

Isso permite que o seu segmento finalize com perfeição o que estava fazendo, deixando seu aplicativo em um bom estado conhecido.

A maneira mais correta e segura para thread é usar um WaitHandle para sinalizar ao thread quando ele deveria parar. Eu principalmente uso ManualResetEvent.

No seu tópico, você pode ter:

 private void RunThread() { while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100))) { // ... } } 

onde this.flag é uma instância de ManualResetEvent. Isso significa que você pode chamar this.flag.Set() de fora do thread para parar o loop.

O método WaitOne só retornará true quando o sinalizador estiver definido. Caso contrário, o tempo limite será atingido após o tempo limite especificado (100 ms no exemplo) e o encadeamento passará pelo loop mais uma vez.

Não é uma boa ideia matar um tópico. É melhor sinalizar que deve parar e deixá-lo terminar normalmente. Existem várias maneiras diferentes de fazer isso.

  • Use Thread.Interrupt para cutucá-lo se estiver bloqueado.
  • Pesquise uma variável de bandeira.
  • Use a class WaitHandle para enviar um sinal.

Não é necessário que eu repita como cada método pode ser usado, pois já fiz isso nesta resposta .

Abortar um encadeamento é uma idéia muito ruim, já que você não pode determinar o que o encadeamento estava fazendo no momento do aborto.

Em vez disso, tenha uma propriedade que o thread possa verificar e que seu código externo possa ser definido. Deixe o thread verificar essa propriedade booleana quando estiver em um local seguro para sair.

Eu concordo com Jon B

 volatile bool shutdown = false; void RunThread() { try { while (!shutdown) { /* Do work. */ } } catch (ThreadAbortException exception) { /* Clean up. */ } } void StopThread() { shutdown = true; } 

Existem também exemplos de kill threads na minha class WebServer …

https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948

Eu diria que o Abort está bem, apenas entenda quais são as ramificações … contanto que você esteja indicando o estado antes de uma tarefa de longa duração O Abort funcionará, mas as flags são necessárias, como (ShouldStop ou ActionBranch etc)

Confira exemplos!