C # Thread Termination and Thread.Abort ()

In MSDN, la descrizione del metodo Thread.Abort () dice: “La chiamata a questo metodo di solito interrompe il thread.”

Perché non SEMPRE?

In quali casi non termina il thread?

Ci sono altre possibilità di terminare i thread?

Thread.Abort() inietta una ThreadAbortException sul thread. La discussione può annullare la richiesta chiamando Thread.ResetAbort() . Inoltre, ci sono alcune parti di codice, come il blocco finally che verrà eseguito prima che l’eccezione venga gestita. Se per qualche motivo il thread è bloccato in tale blocco, l’eccezione non verrà mai sollevata sul thread.

Poiché il chiamante ha pochissimo controllo sullo stato del thread quando chiama Abort() , generalmente non è consigliabile farlo. Passare invece un messaggio alla terminazione di richiesta del thread.

In quali casi non termina il thread?

Questa domanda è un duplicato.

Cosa c’è di sbagliato nell’uso di Thread.Abort ()

Ci sono altre possibilità di terminare i thread?

Sì. Il tuo problema è che non dovresti mai iniziare una discussione che non puoi dire in modo educato di interrompere e si arresta in modo tempestivo. Se ti trovi in ​​una situazione in cui devi avviare un thread che potrebbe essere (1) difficile da fermare, (2) bacato, o peggio di tutto (3) ostile all’utente, allora la cosa giusta da fare è fare un nuovo processo, avviare il thread nel nuovo processo e quindi terminare il processo quando si desidera che il thread si interrompa. L’unica cosa che può garantire la chiusura sicura di un thread non cooperativo è il sistema operativo che blocca l’intero processo.

Vedi la mia risposta eccessivamente lunga a questa domanda per maggiori dettagli:

Utilizzo dell’istruzione di blocco all’interno di un ciclo in C #

Il bit pertinente è il bit alla fine in cui discuto quali sono le considerazioni su quanto a lungo dovresti aspettare che un thread si uccida prima di interromperlo.

Perché non SEMPRE? In quali casi non termina il thread?

Per i principianti, un thread può intercettare una ThreadAbortException e annullare la propria terminazione. Oppure potrebbe eseguire un calcolo che richiede un’eternità mentre stai tentando di annullarlo. Per questo motivo, il runtime non può garantire che il thread terminerà sempre dopo averlo richiesto.

ThreadAbortException ha più:

Quando viene effettuata una chiamata al metodo Abort per distruggere un thread, il Common Language Runtime genera una ThreadAbortException. ThreadAbortException è un’eccezione speciale che può essere rilevata, ma verrà automaticamente rilanciata alla fine del blocco catch. Quando viene sollevata questa eccezione, il runtime esegue tutti i blocchi finally prima di terminare il thread. Poiché il thread può eseguire un calcolo illimitato nei blocchi finally o chiamare Thread.ResetAbort() per annullare l’interruzione, non vi è alcuna garanzia che il thread finirà mai.

Non è necessario Abort() un thread manualmente. Il CLR farà tutto il lavoro sporco per te se lasci semplicemente il metodo nel ritorno del thread; che terminerà normalmente il filo.

FileStream.Read() a una named pipe che non sta attualmente ricevendo nulla (leggi i blocchi di chiamata mentre attende i dati in arrivo) non risponderà a Thread.Abort() . Rimane all’interno della chiamata a Read() .

Cosa succede se un thread è in possesso di un lucchetto e viene interrotto / ucciso? Le risorse rimangono bloccate

Funziona bene quando quando un thread chiama abort se stesso ma non da altro thread. Interrompi, termina forzatamente il thread interessato anche se non ha completato la sua attività e non fornisce alcuna opportunità per la pulizia delle risorse

riferimento MSDN


vedere: Best practice per il threading gestito

ThreadAborts non si verificherà all’interno di un blocco finally o tra BeginCriticalRegion e EndCriticalRegion

Perché puoi prendere l’ Thread.ResetAbort ThreadAbortException e chiamare Thread.ResetAbort all’interno del gestore.

Non riesco a interrompere un thread bloccato in un loop:

 //immortal Thread th1 = new Thread(() => { while (true) {}}); 

Posso comunque interrompere il thread se dorme durante il ciclo:

 //mortal Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }}); 

OT: Per un approccio completo, indipendente dalla lingua, discutibilmente utile e dannatamente divertente, vedi Verity Stob !

Ho avuto casi in cui il thread è stato troppo impegnato per ascoltare la chiamata Abort (), che di solito genera una ThreadAbortingException generata nel mio codice.