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 :

Déclarer un thread contenant une méthode avec paramètre WinForm


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Janvier 2014
    Messages : 63
    Points : 44
    Points
    44
    Par défaut Déclarer un thread contenant une méthode avec paramètre WinForm
    Bonjour à tous et toutes,

    Je me confronte à un problème lors de mon développement, je souhaite démarrer un thread lorsque l'on appui sur un bouton.
    Dans ce thread, je souhaite faire référence à une méthode appelé lectureSpooler(nomIMP) et qui à donc en paramètre un string appelé "nomIMP".

    Dans mon bouton j'ai donc essayé de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Thread t1 = new Thread (new ThreadStart(lectureSpooler(nomIMP)));
                t1.Start();
    Seulement, j'ai le code erreur "Nom de méthode attendu" qui ressort justement sur la ligne de déclaration de mon thread.

    Auriez vous une idée?

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Tout d'abord, quand tu déclares ta variable de type "Thread", tu initialises une sorte de "pointeur de fonction" comme paramètre, donc il ne faut pas mettre le paramètre à ce moment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread t1 = new Thread (new ParameterizedThreadStart(lectureSpooler));
    Note bien ici que j'ai utilisé le constructeur de thread avec un argument de type ParameterizedThreadStart pour dire qu'il s'agit d'une fonction qui admettra un paramètre.

    Nous en arrivons donc au problème suivant : parmi les surcharges de "Thread", il n'y a pas d'argument qui indique que la fonction à passer est de type string. Il y a 2 possibilités :
    - soit tu transformes ta fonction "lectureSpooler" pour qu'elle ait un paramètre de type "object" mais là ce n'est pas terrible comme solution.
    - soit tu passe une expression lambda comme argument du Thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread t1 = new Thread (new ParameterizedThreadStart(obj => { lectureSpooler((string)obj); } ));
    ainsi, pas besoin de modifier ta fonction.
    Note bien que l'on peut raccourcir la déclaration ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread t1 = new Thread (obj => { lectureSpooler((string)obj); } );
    Enfin, dernière question : comment passer l'argument au thread? Eh bien ça se passe au moment de la demande de démarrage du thread tout simplement :
    N'hésites pas à consulter la documentation MSDN de Thread pour plus de détails.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Janvier 2014
    Messages : 63
    Points : 44
    Points
    44
    Par défaut
    Merci pour cette solution, cela semble fonctionner.

    Seulement on autre problème apparait, mon thread t1 lance donc ma méthode lectureSpooler.

    Dans cette méthode, j'écris quelque chose dans une textBox, seulement rien ne s'écrit et j'ai même une erreur, "System.InvalidOperationException: Opération inter-threads non valide : le contrôle 'textBox1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été crée."

    Il me semble avoir déjà entendu parler de çà justement concernant les threads en WinForm, mais je ne me souviens plus ou j'avais vu çà..

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Janvier 2014
    Messages : 63
    Points : 44
    Points
    44
    Par défaut
    Solution trouvé à l'instant sur un tuto d'un autre site.

    Il suffit en faite de créer un delegate qui à les droit sur le controle, vu qu'il appartient au thread principal.
    Puis de l'appeler avec un invoke.

    Dans mon cas cela donne
    Pour la méthode lectureSpooler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (nomIMP == "iram0101") 
    {
        Invoke((montrerSpool)ajoutTB, System.IO.Path.GetFileName(files[i]));
    }
    Pour le delegate:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public delegate void montrerSpool(string valeur);
    La petite methode d'affichage qui est appelé grace au delegate (lui même appelé par mon thread enfant avec la commande Invoke):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void ajoutTB(string valeur)
            {
                textBox1.Text += (valeur)+Environment.NewLine;
            }

    Voila pour la solution au problème, juste une petite chose, je n'arrive pas à comprendre la synthaxe du code que tu m'a proposé , serait-il possible d'avoir une petite explication?

  5. #5
    Invité
    Invité(e)
    Par défaut
    En effet, il est absolument capital de savoir que les fonctions et propriétés d'un élément d'interface utilisateur ne doivent impérativement être utilisées que dans le thread qui a créé cet élément.
    Pour mettre à jour un élément d'interface utilisateur avec une info d'un autre thread, il faut appeler une fonction de "synchronisation" qui va faire un "PostMessage" ou un "SendMessage" au thread de l'interface utilisateur.

    Sous WinForm, la classe de base "Control" dispose d'une fonction Invoke qui permet d'appeler une fonction sur le thread de l'élément d'interface utilisateur.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    string monInfoSurMonAutreThread;
    //...
    //Code qui met "monInfoSurMonAutreThread" à jour
    //...
    Invoke((Action)(()=>{ textBox.Text = monInfoSurMonAutreThread }));
    //...
    Alors là en plus c'est un peu particulier : l'argument est de type "Delegate" ce qui veut dire qu'il peut s'agir de n'importe quelle signature compatible (c'est le "object" pour les classes normales si tu veux). Alors je lui dit de quel type de délégué il s'agit, d'où le cast de mon expression lambda en "Action".

    Une version compatible Framework 2.0 serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Invoke((Action) delegate() { textBox.Text = monInfoSurMonAutreThread });
    ça permet pour ce cas de mettre moins de parenthèses à cause du cast.

    [EDIT]
    Citation Envoyé par FruitSellers Voir le message
    Voila pour la solution au problème, juste une petite chose, je n'arrive pas à comprendre la syntaxe du code que tu m'a proposé , serait-il possible d'avoir une petite explication?
    Peut-être parles-tu des expressions lambda? Elles permettent de créer des fonctions "à la volée" dans ta fonction.
    Regardes donc le lien que je viens de te mettre pour t'informer dessus.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Janvier 2014
    Messages : 63
    Points : 44
    Points
    44
    Par défaut
    En effet il s'agissait bien de çà, merci pour les tuyaux et le coup de pouce!

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

Discussions similaires

  1. Appel à une fonction avec paramètre contenant apostrophe
    Par tomy29 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 02/02/2012, 19h10
  2. Utiliser une méthode avec paramètres
    Par SI_BDD dans le forum JSF
    Réponses: 18
    Dernier message: 05/05/2011, 18h40
  3. Executer une fonction (avec paramètres) dans un thread secondaire
    Par you38 dans le forum Threads & Processus
    Réponses: 21
    Dernier message: 06/08/2010, 08h12
  4. appel d'une méthode avec plusieurs paramètres
    Par soujava dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 11/05/2008, 23h30
  5. appeler une méthode avec paramètre dans une page JSP
    Par javasmif dans le forum Struts 2
    Réponses: 1
    Dernier message: 06/12/2007, 10h48

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