IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Interrompre un thread [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2012
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2012
    Messages : 12
    Par défaut Interrompre un thread
    J'essaye d'utiliser un thread dans une Windows Forms, mais je rencontre un problème lorsque j'utilise la croix pour fermer la fenêtre avant la fin du thread. Le thread ne semble pas s'interrompre correctement.
    Cela me lance une exception : 'Object Disposed Exception' cannot access a dispoded object

    Merci de votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
         public partial class Form1 : Form
        {
     
            private bool thread_stop = false;
            Thread t=null;
            public delegate void deleg(string x);
     
            private void button1_Click(object sender, EventArgs e)
            {
                t = new Thread(new ThreadStart(le_thread));
                thread_stop = false;
                t.Start();
            }
     
            public void le_thread()
            {
                Random r = new Random();
                int res = 0;
                for (int i = 1; i < 1000; i++)
                {
                    if (thread_stop) { return; }
     
                    Invoke((deleg)maj_txt, i.ToString());
     
                    for (int j = 1; j < 1000; j++)
                    {
                        for (int k = 1; k < 1000; k++)
                        {
                            res = k + r.Next();
                        }
                    }
                }
            }
     
            public void maj_txt(string x)
            {
                info.Text = x;
            }
     
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                thread_stop = true;
                if(t!=null)
                    if (t.IsAlive || t.ThreadState == System.Threading.ThreadState.Running)
                    {
                        t.Join(1000);
                    }
     
            }
        }

  2. #2
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 64
    Par défaut
    Bonjour,

    D'après ce que j'ai lu, normalement les Threads se ferment automatiquement. Donc es-tu sûr que c'est ton Thred qui pose un problème.
    Deuxièmement, es-tu sûr de cette syntaxe :
    En regardant la méthode sur le MSDN, on dirait que ta méthode n'attend pas d'attribut.

    Cordialement,
    Clemou01

  3. #3
    Membre averti
    Inscrit en
    Septembre 2012
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2012
    Messages : 12
    Par défaut
    Bonjour Clemou01,

    Mon problème vient du fait que je veux interrompre le thread lors de l'évènement 'FormClosing' qui est déclenché lorsque l'on clique sur la croix rouge de la fenêtre, si je le stop à un autre moment ça marche.
    Pour le Join j'ai essayé sans argument la fenêtre ne se ferme pas et reste bloquée.

    Merci

  4. #4
    Membre Expert
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 662
    Par défaut
    Join() n'est pas vraiment fait pour ça , essaye plutôt ça :


  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 93
    Par défaut
    Salut,

    Le soucis se trouve dans ta méthode Invoke() je pense : lorsque tu cliques sur la croix pour fermer l'application, la textbox est "disposed", et lorsque tu veux y affecter ta valeur il te balance l'exception.

    Si j'étais toi je ne m'embêterais pas avec les threads : regarde du côté du BackgroundWorker.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Ton idée de fermer proprement le thread est une bonne idée. Après, il y a 2 soucis qui sont combinés : dans ta grosse boucle, tu testes ta variables "thread_stop" à un niveau trop haut, du coup, lorsque tu fais le "Join", tu n'attends qu'une seconde et tu sors tout de suite... Pendant ce temps, dans le thread, avec "Invoke" tu tentes d'accéder à un contrôle qui n'existe plus.
    La solution rapide dans ce cas, consiste à déplacer le test du "thread_stop" à un niveau plus bas dans l'imbrication des boucles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public void le_thread()
            {
                Random r = new Random();
                int res = 0;
                for (int i = 1; i < 1000; i++)
                {
     
                    Invoke((deleg)maj_txt, i.ToString());
     
                    for (int j = 1; j < 1000; j++)
                    {
                        for (int k = 1; k < 1000; k++)
                        {
                            if (thread_stop) { return; }
                            res = k + r.Next();
                        }
                    }
                }
            }
    Après, il va faire les tests plus souvent mais bon...

    Moi je te conseille d'utiliser la classe "Task" à la place de la classe Thread...

    Au passage, petit commentaire sur les autres réponses
    Citation Envoyé par clemou01 Voir le message
    Bonjour,

    D'après ce que j'ai lu, normalement les Threads se ferment automatiquement. Donc es-tu sûr que c'est ton Thred qui pose un problème.
    Deuxièmement, es-tu sûr de cette syntaxe :
    En regardant la méthode sur le MSDN, on dirait que ta méthode n'attend pas d'attribut.

    Cordialement,
    Clemou01
    Tu as râté la surcharge avec un entier ici. La surcharge de thomas existait bien...

    Citation Envoyé par thomas55 Voir le message
    Pour le Join j'ai essayé sans argument la fenêtre ne se ferme pas et reste bloquée.
    Oui, en effet pour la raison évoquée plus haut...

    Citation Envoyé par PixelJuice Voir le message
    Join() n'est pas vraiment fait pour ça , essaye plutôt ça :

    Ah oui, ça fonctionne pour cette situation mais c'est très violent et ce n'est plus recommandé par Microsoft. Dans ce cas-ci, ça ne pose pas de problème mais si on est dans un contexte d'écriture dans un fichier ou une base de données par exemple cela risque de compromettre l'intégrité des données.
    Encore une fois, la classe "Task" et le "Task-based Asynchronous Pattern" sont recommandés dans tous les cas, les classes "Thread" et "BackgroundWorker" sont hasbeen. Le "TAP" permet d'inclure un jeton d'annulation permettant d'indiquer juste à la tâche qu'on demande son arrêt mais c'est la tâche qui va décider quel est le moment le plus opportun pour s'arrêter.

    Citation Envoyé par Jaco67 Voir le message
    Si j'étais toi je ne m'embêterais pas avec les threads : regarde du côté du BackgroundWorker.
    BackgoundWorker est hasbeen maintenant. Voici le lien que je montrerai plutôt :
    http://msdn.microsoft.com/fr-fr/libr...v=vs.110).aspx

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Interrompre une thread grace au signaux.
    Par code_vx dans le forum C++
    Réponses: 7
    Dernier message: 29/05/2013, 21h49
  2. Thread interrupt, comment interrompre une API tout en libérant les ressources
    Par rpelissi dans le forum Concurrence et multi-thread
    Réponses: 0
    Dernier message: 19/10/2009, 13h30
  3. [GLib] Interrompre un appel bloquant dans un thread
    Par Zorgblub dans le forum Réseau
    Réponses: 3
    Dernier message: 17/11/2007, 18h02
  4. [thread ] interrompre un thread ?
    Par yann_p dans le forum Concurrence et multi-thread
    Réponses: 18
    Dernier message: 27/04/2006, 14h27
  5. [Thread] Interrompre un Thread
    Par Arnaud51 dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 13/03/2005, 21h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo