In MSDN, la descrizione del metodo Thread.Abort () dice: "La chiamata a questo metodo in genere termina il thread."
Perché non SEMPRE?
In quali casi non termina il thread?
Esistono altre possibilità per terminare i thread?
In MSDN, la descrizione del metodo Thread.Abort () dice: "La chiamata a questo metodo in genere termina il thread."
Perché non SEMPRE?
In quali casi non termina il thread?
Esistono altre possibilità per terminare i thread?
Risposte:
Thread.Abort()
inietta una ThreadAbortException
sul thread. Il thread può annullare la richiesta chiamando Thread.ResetAbort()
. Inoltre, ci sono alcune parti di codice, come il finally
blocco che verrà eseguito prima che l'eccezione venga gestita. Se per qualche motivo il thread è bloccato in un tale blocco, l'eccezione non verrà mai sollevata sul thread.
Poiché il chiamante ha pochissimo controllo sullo stato del thread durante la chiamata Abort()
, in genere non è consigliabile farlo. Passa invece un messaggio al thread che richiede la terminazione.
In quali casi non termina il thread?
Questa domanda è un duplicato.
Cosa c'è di sbagliato nell'usare Thread.Abort ()
Esistono altre possibilità per terminare i thread?
Sì. Il tuo problema è che non dovresti mai avviare un thread che non puoi dire educatamente di interrompere e si interrompe in modo tempestivo. Se ti trovi in una situazione in cui devi avviare un thread che potrebbe essere (1) difficile da fermare, (2) bug 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 terminazione sicura di un thread non collaborativo è il sistema operativo che interrompe l'intero processo.
Vedi la mia risposta eccessivamente lunga a questa domanda per maggiori dettagli:
Utilizzo dell'istruzione lock all'interno di un ciclo in C #
Il bit rilevante è il bit alla fine in cui discuto quali sono le considerazioni su quanto tempo 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ò catturare un ThreadAbortException
e annullare la propria terminazione. Oppure potrebbe eseguire un calcolo che richiede un'eternità mentre stai cercando di interromperlo. Per questo motivo, il runtime non può garantire che il thread terminerà sempre dopo che lo hai chiesto.
ThreadAbortException
ha di più:
Quando viene effettuata una chiamata al metodo Abort per eliminare un thread, Common Language Runtime genera un'eccezione ThreadAbortException. ThreadAbortException è un'eccezione speciale che può essere catturata, ma verrà automaticamente sollevata di nuovo alla fine del blocco catch. Quando viene sollevata questa eccezione, il runtime esegue tutti i blocchi finalmente prima di terminare il thread. Poiché il thread può eseguire un calcolo illimitato nei blocchi finalmente 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 che il metodo nel thread ritorni; che terminerà il thread normalmente.
Cosa succede se un thread tiene un lucchetto e viene interrotto / ucciso? Le risorse rimangono bloccate
Funziona bene quando quando un thread chiama interrompe se stesso ma non da un 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
Non riesco a interrompere un thread bloccato in un ciclo:
//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); }});
ThreadAborts non si verificherà all'interno di un blocco finally o tra BeginCriticalRegion e EndCriticalRegion
Perché puoi catturare il ThreadAbortException
e chiamare Thread.ResetAbort
all'interno del gestore.
OT: Per un approccio completo, indipendente dalla lingua, discutibilmente utile e dannatamente divertente sulla concorrenza, vedi Verity Stob !
Ho avuto casi in cui il thread era troppo occupato per ascoltare la chiamata Abort (), che di solito si traduce in un'eccezione ThreadAbortingException lanciata al mio codice.