2009-04-05 5 views
2

Je ne sais pas pourquoi mais je ne peux plus interrompre mon propre thread.L'interruption de thread C# a cessé de fonctionner

thread = new Thread(new ParameterizedThreadStart(this.doWork)); 
thread.Start(param); 
... 
thread.Interrupt(); 
//in doWork() 
try { 
... 
} 
catch (System.Threading.ThreadInterruptedException) 
{ 
//it never hits here. it use to 
} 

je recherche et je n'ai pas de prises dans mon code, ce qui est le seul hic (System.Threading.ThreadInterruptedException). Alors, quoi de neuf? En utilisant le débogueur, je peux voir mon code parcourir le thread.Interrupt() ;. Si je fais thread.abort() je vais attraper une exception System.Threading.ThreadAbortException. Pourquoi attrape-t-il cela et pas ThreadInterruptedException?

Répondre

4

De BOL:

Interruptions un fil qui est dans l'état de fil de WaitSleepJoin.

Si ce fil est pas bloqué dans une attente, le sommeil, ou se joindre à l'état , il sera interrompu quand il commence à côté de bloquer.

ThreadInterruptException est lancé dans le thread interrompu, mais pas jusqu'à ce que le thread se bloque. Si le fil ne bloque jamais, l'exception est jamais jeté , et donc le fil peut complète sans jamais être interrompu

BTW, vous pourriez être mieux en utilisant la classe BackgroundWorker qui prend en charge l'annulation.

+0

+1. Les threads d'interruption devraient généralement être évités - utilisez un mécanisme d'annulation plus gracieux. –

+0

On dirait qu'il ne devrait pas interrompre du tout (je me demande comment je l'ai fait en premier). Donc .abort est une meilleure option? Ce que je veux faire est tuer le fil mais l'avoir exister et appeler quelques fonctions au lieu de la mort pure et simple –

+0

Il est généralement préférable de signaler le fil pour terminer gracieusement, plutôt que de le tuer –

0

De commentaire de acidzombie24 à un autre answer:

Alors .abort est une meilleure option? Ce que je veux faire est de tuer le fil mais l'avoir exister et appeler quelques fonctions au lieu de la mort pure et simple

Quelque chose comme un événement serait mieux.

En supposant que vous souhaitez pouvoir signaler chaque thread séparément, avant que chaque thread de travail ne soit démarré, créez un AutoResetEvent et transmettez-le au thread.

Lorsque vous souhaitez interrompre le thread, appelez Set sur l'événement. Dans le thread de travail vérifier l'état de l'événement régulièrement:

if (theEvent.WaitOne(TimeSpan.Zero)) { 
    // Handle the interruption. 
} 

(Régulièrement: doit être défini par les exigences: les frais généraux de la vérification par rapport à la latence d'interruption.)

Pour avoir une interruption de maître, Pour signaler à tous les travailleurs, utilisez un ManualResetEvent qui restera allumé, et continuez d'interrompre les threads lorsqu'ils vérifient, jusqu'à ce qu'ils soient explicitement Reset.

Questions connexes