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 :

Problème accès thread principal depuis un autre thread


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 25
    Points : 11
    Points
    11
    Par défaut Problème accès thread principal depuis un autre thread
    Bien le bonjour à tous,

    Je modifie actuellement une application graphique et je suis confronté à un problème concernant le multi-threading.
    Jusqu'à présent, l'ouverture d'un fichier dans le programme se faisait dans le thread principal, ce qui freezait l'interface mais ne gênait pas.
    Je souhaiterais maintenant ajouter une barre de chargement qui indique les actions en cours lors de l'ouverture d'un fichier. J'ai donc dû créer un nouveau thread :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    loadingThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(LoadFile));
     
                loadingThread.Start(filePath);
    Dans cette fonction je crée un objet qui devra par la suite mettre à jour la fenêtre. J'ai donc choisi d'en faire un attribut de cet objet. Seulement, lorsque je crée la fenêtre pop-up qui affiche les informations j'ai une erreur comme quoi le thread n'est pas en mode STA :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    LoadFile(string filepath)
    {
    MonitoredSystem = new MonitoredSystem();
     
      MonitoredSystem.progressBarWindow = new ProgressBarWindow();
      MonitoredSystem.progressBarWindow.SetStatus("Début");
    }
    Je me dis donc qu'il faut que la fenêtre soit créée dans le thread principal, le thread graphique, et pas dans le thread secondaire. J'utilise alors le dispatcher de l'application pour ré-utiliser le thread graphique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    LoadFile(string filepath)
    {
    MonitoredSystem = new MonitoredSystem();
     
    Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate { MonitoredSystem.progressBarWindow = new ProgressBarWindow(); })); 
    Dispatcher.Inovke((DispatcherPriority.Send, new Action(delegate {MonitoredSystem.progressBarWindow.SetStatus("Début")}));
    }
    Quand je fais cela, je peux voir que dans le débugger que rien ne se passe, ma fenêtre n'est pas créée.
    J'ai donc essayé le VerifyAccess() mais ca me retourne une exception.. D'après la doc msdn c'est normal car "Seul le thread sur lequel le Dispatcher a été créé peut accéder au Dispatcher."

    Mais partant de là, aucun thread ne crée le thread pricipal, donc on ne peut jamais y accéder !

    Pourriez-vous me dire d'abord si ma façon d'aborder le problème semble correcte, ensuite comment je peux accéder au thread principal pour lui faire exécuter des actions?

    Merci à tous !

  2. #2
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    Essaye d'utiliser ce bout de code :
    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
    using System.Threading;
    //dans ta classe tu déclares : 
    private readonly SynchronizationContext syncContext;
     
    //dans le contructeur : 
    this.syncContext = SynchronizationContext.Current;
     
    //dans ta fonction
    LoadFile(string filepath)
    {
         this.syncContext.Send(delegate
         {
              MonitoredSystem = new MonitoredSystem();
              MonitoredSystem.progressBarWindow = new ProgressBarWindow();
              MonitoredSystem.progressBarWindow.SetStatus("Début");
         }, null);
    }
    j'utilise toujours cette méthode lorsque je suis en multi-threading

  3. #3
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 25
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup, ça a l'air de fonctionner. En fait, cette méthode permet de se passer de Dispatcher c'est bien ca? C'est un peu bourrin à mon avis mais ca aide bien pour les threads graphiques.

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

Discussions similaires

  1. Lancé un thread SwingWorker depuis un autre thread SwingWorker
    Par romuluslepunk dans le forum EDT/SwingWorker
    Réponses: 5
    Dernier message: 14/03/2009, 18h58
  2. Threads. Peut-on appeler la méthode d'un thread depuis un autre thread ?
    Par Pierre8r dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 05/12/2008, 11h48
  3. CreateMDIWindow depuis un autre thread
    Par DjiZ dans le forum Windows
    Réponses: 2
    Dernier message: 03/12/2008, 10h01
  4. Réponses: 3
    Dernier message: 19/03/2008, 09h38
  5. [VB.NET/2.0] Comment MAJ ListBox depuis un autre Thread ?
    Par ShaVo dans le forum Windows Forms
    Réponses: 1
    Dernier message: 12/02/2006, 13h48

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