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

Windows Forms Discussion :

UI & Threading


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 141
    Par défaut UI & Threading
    Bonjour,

    J'aimerais afficher sur mon UI le nombre de fichiers pdf se trouvant dans certains dossiers spécifiques du pc host. Sachant que ce nombre peut varier d'un moment à l'autre, j'aimerais le calculer toutes les 15 secondes.
    Pour ce faire, je démarrer un thread qui se charge de compter le nombre de fichiers, et de mettre à jour l'UI.

    Cependant, j'ai l'impression que ce thread ne rend pas la main au thread UI, ce qui fait que mon UI n'est pas rafraichie (le calcul s'effectue bien, lui).

    Mon 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
    18
    19
    20
    21
    22
    23
    24
     
    while (true)
                {              
                    if (this.listviewHotfolders.InvokeRequired)
                    {
                        this.Invoke(new countJobsCallBack(countJobs));
                    }
                    else
                    {
                        for (int i = 0; i < this.listviewHotfolders.Items.Count; i++)
                        {
                            String[] files = Directory.GetFiles(this.listviewHotfolders.Items[i].SubItems[4].Text);
                            int count = 0;
                            foreach (String file in files)
                            {
                                if (Path.GetExtension(file) == ".pdf")
                                    count++;
                            }
                            this.listviewHotfolders.Items[i].SubItems[6].Text = count.ToString();
                        }
                    }
                }
     
    // Les 15 secondes ne sont pas prises en compte ici, mais le problème reste le même

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 114
    Par défaut
    Bonjour,

    Pourrait-on avoir plus de code ?

    La le code que tu nous montre vérifie si il se trouve sur le thread UI (via le InvokeRequired) et si il s'y trouve, il invoke la méthode CountJobs sur le thread ui et sinon il compte le nombre de fichier pdf (si j'ai bien tout compris).

    Je vois plusieurs points d'erreur :
    - ta boucle pour le compte du nombre de fichier pdf devrait être exécuté en dehors du thread UI (ce que tu souhaite) via un thread de la pool (http://msdn.microsoft.com/fr-fr/libr...(v=vs.90).aspx).
    - tu ne devrait pas (ce n'est que mon avis) lire tes données depuis l'UI dans ta boucle de travail (ce que tu fais en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.listviewHotfolders.Items[i].SubItems[4].Text
    )
    - une fois avoir fait tout tes calculs, tu devrait utiliser this.Invoke pour mettre à jour ton UI (ou bien mettre chacun de tes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.listviewHotfolders.Items[i].SubItems[6].Text = count.ToString();
    dans this.Invoke).

    Enfin, pour demander à un thread d'attendre, tu as http://msdn.microsoft.com/fr-fr/libr...(v=vs.90).aspx.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 141
    Par défaut
    Merci pour ta réponse ketan. La méthode que je montre ci-haut est la méthode "CountJobs" et est dans un autre thread que le thread UI (thread lancé dans le constructeur de ma form, je ne sais d'ailleurs pas si c'est le bon endroit pour le faire, bien que je n'en vois pas de meilleur).

    Ce que je veux faire, donc, c'est compter le nombre de fichiers dans chaque dossier repris dans ma listview (et j'ai donc besoin de lire des données dans celle-ci depuis un thread autre que l'UI, puis de la màj).

    Pour y voir plus clair :

    Constructeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            public MainWindow()
            {
                InitializeComponent();
                // ...
                Thread inputJobs = new Thread(new ThreadStart(countJobs));            
                inputJobs.Start();
            }
    CountJobs
    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
     
            public void countJobs()
            {
                while (true)
                {              
                    if (this.listviewHotfolders.InvokeRequired)
                    {
                        this.Invoke(new countJobsCallBack(countJobs));
                    }
                    else
                    {
                        for (int i = 0; i < this.listviewHotfolders.Items.Count; i++)
                        {
                            String[] files = Directory.GetFiles(this.listviewHotfolders.Items[i].SubItems[4].Text);
                            int count = 0;
                            foreach (String file in files)
                            {
                                if (Path.GetExtension(file) == ".pdf")
                                    count++;
                            }
                            this.listviewHotfolders.Items[i].SubItems[6].Text = count.ToString();
                        }
                    }
                    Thread.Sleep(5);
                }
            }

  4. #4
    Membre Expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Par défaut
    Pas de rapport avec l'UI, mais tu peux utiliser la classe FileSystemWatcher, qui envoie un événement si un fichier est ajouté, effacé, modifié : http://msdn.microsoft.com/en-us/libr...emwatcher.aspx

  5. #5
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 141
    Par défaut
    Citation Envoyé par GuruuMeditation Voir le message
    Pas de rapport avec l'UI, mais tu peux utiliser la classe FileSystemWatcher, qui envoie un événement si un fichier est ajouté, effacé, modifié : http://msdn.microsoft.com/en-us/libr...emwatcher.aspx
    Salut Guruu, et merci pour ta réponse.
    Le système est basé en grande partie sur les FileSystemWatchers, mais ceux-ci dépendent d'un service qui n'est pas fortement lié à l'UI, ce qui rend la communication assez difficile. De plus, le nombre de fichiers traités étant assez importants, je ne veux pas un refresh trop régulier de l'UI, et gérer cela serait, je pense, plus compliqué que ce que je propose ici.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 31
    Par défaut
    Je pense que ton thread prends trop de ressources.
    Tu dois l'endormir lorsque ton traitement est terminé.
    Sleep(5) n'est probablement pas efficace car le système est incapable de faire une attente de 5ms.
    J'utilise plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public ManualResetEvent m_SleepEvent = new ManualResetEvent(false);
    dans la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
                m_SleepEvent.Reset(); // Initialisation
                while (true)
                {
                      // Ton traitement
                      m_SleepEvent.WaitOne();   // On reste bloqué
                      m_SleepEvent.Reset();       // On réarme
                }
    Dans la routine qui gère les 15 s, tu fait un Set pour le réveiller.
    Tu peux aussi utiliser un système équivalent pour quitter le thread "proprement".
    Je ne suis pas rentré dans les détails, mais le principe est là.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    m_SleepEvent.Set();

  7. #7
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 141
    Par défaut
    Bonjour alro,

    Merci pour ta réponse. J'avais essayé via des AutoResetEvent, l'affichage ne se faisait qu'une fois, mais le soucis restait le même par la suite. Pareil ici, avec les ManualResetEvent...

    J'ai réussi à faire ce que je voulais via un timer (et non un thread travail), mais je ne suis pas sur que ce soit la meilleure solution dans ce cas-ci...

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 31
    Par défaut
    Le problème du timer, c'est que ça bloque tout le reste pendant son exécution.
    Par contre, le timer peut très bien lancer le thread (ton thread sans la boucle while(true)).

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

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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