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 :

tache lourde avec threads


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 14
    Par défaut tache lourde avec threads
    Salut tout le monde

    Je développe une application, détecter les routes et dessiner leurs bordures sur l’image…, en c# qui exécute des fonctions lourdes se trouvant toutes dans une seule classe et qui font appel les unes aux autres.

    J’ai besoin de rajouter une fonction qui consiste à arrêter l’exécution à un moment donné pour se contenter du résultat préliminaire, ceci doit être fait avec les threads et la méthode invoke…

    A présent je ne parviens pas à ce résultat, en appuyant sur la forme en plein exécution celle-ci devient bloquante, merci de me donner une idée comment le faire.

    Voici le schéma approximatif :

    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
    private void ButtonExecute_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(launchInvoke));
        t.Start();
    }
     
    private void launchInvoke()
    {
        pictureBox1.Invoke(new myDelegate (myclasse.myMethode), this);
    }
     
    private delegate void myDelegate(baseForm bForm);
    private void ButtonStop_Click(object sender, EventArgs e)
    {
        Stop = true;
    }
     
    myclasse.myMethode se charge de trouver les points des bordures et de les mettre dans un ArrayList soit arrayListPoints, puis dans l’évènement :
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
         // dessiner les bordures en se servant de arrayListPoints
    }

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Ton traitement lourd je suppose que c'est
    Le problème c'est qu'avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pictureBox1.Invoke(new myDelegate (myclasse.myMethode), this);
    Tu demandes à exécuter cette méthode sur le thread principal (Invoke). Résultat ton thread ne sert absolument à rien

    Invoke ne doit être utilisé que lorsque l'on a besoin d'accéder à la partie graphique (afin d'utiliser le thread principal, seul thread autorisé à faire ce genre d'opérations).

    Regarde si le BackgroundWorker ne peut pas t'aider (exécution d'une tâche en fond, avec événement de progression et de fin et possibilité d'annuler l'opération).

  3. #3
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 14
    Par défaut Graphisme
    J’ai testé ta proposition avec le backgroundWorker.
    Cela m’a résolu le problème du parallélisme ie mon formulaire (baseForm) est tout à fait indépendant de l’exécution de la tâche de fond (extraction) par myMethode.
    Par contre, il reste le problème du dessin des bordures, parce que dans myclasse.myMethode je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bForm.pictureBox1.Refresh();
    ce qui me signale une erreur
    accès à un contrôle par un thread autre que celui qui l’a crée
    .
    J’ai du ensuite désactiver la génération de cette exception par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Control.CheckForIllegalCrossThreadCalls = false;
    (ce qui n’est pas recommandé).
    De ce fait, j’ai obtenu une execution (normale) mais sans que les bordures ne soient dessinées sur l’image (pictureBox1_Paint n’est jamais appelée).
    J’ai pensé également de faire (sur la classe myClass) :

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private delegate void delegateRefresh (object sender, PaintEventArgs e);
     
    private static void pictureBox1Refresh()
    {
       bForm.pictureBox1.Refresh();   // bForm : mon formulaire de base
    }
     
    private static void myMethode (baseForm bForm)
    {
       // extraction c.à.d. calcule des points des bordures et les mettre dans
       // arrayListPoints
     
      bForm.pictureBox1.Invoke(new delegateRefresh(bForm.pictureBox1_Paint), [param]);
    }

    Je ne sais pas si cette solution pourrai être juste, mais ma difficulté actuelle réside sur le passage des paramètres [param] (la création d’un object et d’un PaintEventArgs).
    Merci de m’aider à continuer cette solution ou de me proposer une autre.

  4. #4
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    236
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Octobre 2007
    Messages : 236
    Par défaut
    Je sais pas si j'ai bien compris le problème décrit dans ce post ou si je suis à coté de la plaque mais il se peut que ce bout de code serve à quelque chose

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    using System;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;
     
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            // Thread de traitement de l'image
            Thread processImageThread = null;
            // Fin de la Thread si true
            bool processImageStop = false;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void pictureBox1_Click(object sender, EventArgs e)
            {
                // Pour ne pas intérrompre prématurément le Thread
                processImageStop = false;
                this.Text = "Traitement de l'image en cours...";
                // Création et lancement du Thread
                processImageThread = new Thread(ProcessImage);
                processImageThread.Start(pictureBox1.Image);
                // Attendre la fin du traitement
                while (processImageThread.IsAlive) Application.DoEvents();
                // Traitement terminé ou intérompu
                if (!processImageStop)
                {
                    this.Text = "Terminé avec succès.";
                }
                else
                {
                    this.Text = "Interrompu!";
                }
                // Afficher le résultat
                pictureBox1.Refresh();
            }
     
            private void ProcessImage(object data)
            {
                // Juste un exemple d'une tache qui prend du temps
                Bitmap bmp = (Bitmap)(Image)data;
                for (int y = 0; y < bmp.Height; y++)
                {
                    // Sortir si clique sur button1
                    if (processImageStop) return;
                    for (int x = 0; x < bmp.Width; x++)
                    {
                        Color clr = bmp.GetPixel(x, y);
                        clr = Color.FromArgb(clr.B, clr.G, clr.R);
                        bmp.SetPixel(x, y, clr);
                    }
                }
     
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                // Interrompre le traitement
                processImageStop = true;
            }
        }
    }

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

Discussions similaires

  1. taches paralleles avec thread
    Par nicogigo dans le forum Général Python
    Réponses: 4
    Dernier message: 26/03/2010, 10h39
  2. [SWING] Exception bizarre avec Thread
    Par Gob4 dans le forum Débuter
    Réponses: 2
    Dernier message: 13/09/2005, 21h55
  3. Réponses: 3
    Dernier message: 08/09/2005, 10h45
  4. [MFC] Cherche Timer avec thread
    Par romeo9423 dans le forum MFC
    Réponses: 17
    Dernier message: 09/03/2005, 10h33
  5. Variable static avec thread
    Par oxor3 dans le forum Threads & Processus
    Réponses: 7
    Dernier message: 27/08/2004, 11h45

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