web-dev-qa-db-fra.com

Comment tuer un fil instantanément en C #?

J'utilise la méthode thread.Abort pour tuer le thread, mais cela ne fonctionne pas. Existe-t-il un autre moyen de terminer le fil?

private void button1_Click(object sender, EventArgs e)
{
    if (Receiver.IsAlive == true)
    {
        MessageBox.Show("Alive");
        Receiver.Abort();
    }
    else
    {
        MessageBox.Show("Dead");
        Receiver.Start();
    }
}

J'utilise ceci mais chaque fois que je reçois le statut Alive, Receiver est mon thread global.

46
Mobin

La raison pour laquelle il est difficile de tuer un fil est parce que les concepteurs de langage veulent éviter le problème suivant: votre fil est verrouillé, puis vous le supprimez avant de pouvoir le libérer. Maintenant, tous ceux qui ont besoin de ce verrou resteront bloqués.

Ce que vous devez faire est d'utiliser une variable globale pour indiquer au thread de s'arrêter. Vous devez manuellement, dans votre code de thread, vérifier cette variable globale et renvoyer si vous voyez qu'il indique que vous devez arrêter.

64
redtuna

Vous pouvez tuer instantanément en le faisant de cette façon:

private Thread _myThread = new Thread(SomeThreadMethod);

private void SomeThreadMethod()
{
   // do whatever you want
}

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
   _myThread.Abort();
}

Je l'utilise toujours et travaille pour moi :)

31
Nickon

Vous devriez d'abord avoir une méthode convenue pour mettre fin au fil. Par exemple, un running_valiable que le thread peut vérifier et respecter. 

Votre code de thread principal doit être encapsulé dans un bloc d'exception qui intercepte les exceptions ThreadInterruptException et ThreadAbortException qui nettoieront proprement le thread à la sortie.

Dans le cas de ThreadInterruptException, vous pouvez vérifier la variable running_ pour voir si vous devez continuer. Dans le cas de ThreadAbortException, vous devez ranger immédiatement et quitter la procédure de thread.

Le code qui tente d’arrêter le thread doit faire ce qui suit:

running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
   threadInstance_.Abort();
}
19
Adrian Regan

le thread sera tué quand il aura fini de travailler, donc si vous utilisez des boucles ou autre chose, vous devriez passer variable au thread pour arrêter la boucle après que le thread sera fini.

6
Wael Dalloul

C # Thread.Abort N'EST PAS garanti d'abandonner le thread instantanément. Cela fonctionnera probablement lorsqu'un thread appelle Abort sur lui-même, mais pas lorsqu'un thread en appelle à un autre. 

Veuillez vous reporter à la documentation: http://msdn.Microsoft.com/en-us/library/ty8d3wta.aspx

J'ai rencontré ce problème avec des outils d'écriture qui interagissent avec le matériel. Vous voulez un arrêt immédiat, mais ce n'est pas garanti. J'utilise généralement des drapeaux ou une autre logique pour empêcher l'exécution de parties de code s'exécutant sur un thread (et que je ne souhaite pas exécuter sur des tâches manquantes - délicat). 

4
Sesh
    private void ResumeButton_Click(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            Application.Current.Resources["AutoPilotThreadStatus"] = true;
            Thread.CurrentThread.Name = "ResumeAutoPilot";
            Thread.CurrentThread.IsBackground = true;
            AutoPilotHandler.ResumeAutoPilot();
        });
    }

    public static void ResumeAutoPilot()
    {
        while ((bool)Application.Current.Resources["AutoPilotThreadStatus"])
        {
            CheckAutoPilotThreadStatus();
            var searchYoutube = YoutubeHandler.Search("small truck");
            CheckAutoPilotThreadStatus();
            SaveVideosToDatabase(searchYoutube);
            CheckAutoPilotThreadStatus();
        }
    }

    public static void CheckAutoPilotThreadStatus()
    {
        if (!(bool)Application.Current.Resources["AutoPilotThreadStatus"])
        {
            KillCurrentThread();
        }
    }

    public static void KillCurrentThread()
    {
        Thread.CurrentThread.Abort();
    }
0
Erçin Dedeoğlu