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 :

Thread - problème (Débutant)


Sujet :

C#

  1. #1
    Membre habitué Avatar de Bobybx
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2005
    Messages : 122
    Points : 125
    Points
    125
    Par défaut Thread - problème (Débutant)
    Bonjour,

    je m'y connais très peu en C# et j'y développe pour mon propre apprentissage un petit programme tout bête mettant en action des threads.

    J'ai une picture box que je crée dans une classe et que j'aimerai faire rebondir dans un carré.
    Cette classe est instanciée à l'aide d'un thread, le but étant que 3 balles correspondraient à 3 threads.

    J'ai une erreur dans mon code, pouvez-vous m'aider svp?
    Tout est dans le form1, pas de modules (pour le moment)
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace WindowsApplication2
    {
    
        public partial class Form1 : Form
        {
            ball une_ball;
            ball une_ball2;
    
            ball param;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                une_ball = new ball(100, 50);
                une_ball2 = new ball(400, 400);
                this.Controls.Add(une_ball.maball);
                this.Controls.Add(une_ball2.maball);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                param = une_ball;
                Thread thr_lap1 = new Thread(new ThreadStart(param.LanceThread));
                thr_lap1.Start();
    
                //param = une_ball2;
                //Thread thr_lap2 = new Thread(new ThreadStart(LanceThread));
                //thr_lap2.Start();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
            }
    
        }
    
        public class ball
        {
            public PictureBox maball;
            public PictureBox getMaBalle() { return maball; }
    
            public ball(int x, int y)
            {
                maball = new System.Windows.Forms.PictureBox();
                maball.Image = global::WindowsApplication2.Properties.Resources.Hiver;
                maball.Location = new System.Drawing.Point(x, y);
                maball.Name = "lol";
                maball.Size = new System.Drawing.Size(10, 10);
                maball.TabIndex = 0;
                maball.TabStop = false;
            }
    
    
            public PictureBox pict1 = new System.Windows.Forms.PictureBox();
            public PictureBox getpict1() { return pict1; }
    
    
            public void LanceThread()
            {
                if (pict1.InvokeRequired)
                    pict1.Invoke(new TextBoxInvokeHandler(Avancer));
                else
                    Avancer();
            }
    
            public delegate void TextBoxInvokeHandler();
    
            public void Avancer()
            {
                int x = maball.Location.X;
                int y = maball.Location.Y;
                //int x = this.pictureBox1.Location.X;
                //int y = this.pictureBox1.Location.Y;
                int dx = -1;
                int dy = -4;
                int vitesse = 5;
    
                Random Randomclass = new Random();
    
                for (; ; )
                {
                    int param_x = x;
                    param_x += dx * vitesse;
    
                    if ((param_x > 490) || (param_x < 100))
                        dx = -dx;
    
                    int param_y = y;
                    param_y += dy * vitesse;
    
                    if ((param_y > 440) || (param_y < 50))
                        dy = -dy;
    
                    x += dx * vitesse;
                    y += dy * vitesse;
    
                    maball.Location = new System.Drawing.Point(x, y);
                    Thread.Sleep(50);
                }
    
                //this.pictureBox1.Location = new System.Drawing.Point(100, 50);
                //this.pictureBox1.Location = new System.Drawing.Point(490, 440);
    
            }
        }
    }
    L'erreur se trouve ici puisqu'il me dit j'accede déjà à maball.location via un autre thread. Or j'ai un invoke pour éviter ceci...

    Merci d'avance.

  2. #2
    Membre habitué Avatar de Bobybx
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2005
    Messages : 122
    Points : 125
    Points
    125
    Par défaut
    Re,

    Bon je viens de modifier mon code et je viens de résoudre ce souci.
    Mon seul problème est que je n'ai qu'une seule balle qui avance maintenant.

    Pourtant mes 2 threads ont l'air lancés. Est-ce dûe à la boucle infinie qui attendrait pour lancer le 2ème thread

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
     
    namespace WindowsApplication2
    {
     
        public partial class Form1 : Form
        {
            ball une_ball;
            ball une_ball2;
     
            ball param;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                une_ball = new ball(100, 50);
                une_ball2 = new ball(400, 400);
                this.Controls.Add(une_ball.maball);
                this.Controls.Add(une_ball2.maball);
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                param = une_ball;
                Thread thr_lap1 = new Thread(new ThreadStart(param.LanceThread));
                thr_lap1.Start();
     
                param = une_ball2;
                Thread thr_lap2 = new Thread(new ThreadStart(param.LanceThread));
                thr_lap2.Start();
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
            }
     
        }
     
        public class ball
        {
            public PictureBox maball;
     
            public ball(int x, int y)
            {
                maball = new System.Windows.Forms.PictureBox();
                maball.Image = global::WindowsApplication2.Properties.Resources.Hiver;
                maball.Location = new System.Drawing.Point(x, y);
                maball.Name = "lol";
                maball.Size = new System.Drawing.Size(10, 10);
                maball.TabIndex = 0;
                maball.TabStop = false;
            }
     
     
            public PictureBox pict1 = new System.Windows.Forms.PictureBox();
            public PictureBox getpict1() { return pict1; }
     
     
            public void LanceThread()
            {
                if (maball.InvokeRequired)
                    maball.Invoke(new TextBoxInvokeHandler(Avancer));
                else
                    Avancer();
            }
     
            public delegate void TextBoxInvokeHandler();
     
            public void Avancer()
            {
                int x = maball.Location.X;
                int y = maball.Location.Y;
                //int x = this.pictureBox1.Location.X;
                //int y = this.pictureBox1.Location.Y;
                int dx = -1;
                int dy = -4;
                int vitesse = 5;
     
                Random Randomclass = new Random();
     
                for (; ; )
                {
                    int param_x = x;
                    param_x += dx * vitesse;
     
                    if ((param_x > 490) || (param_x < 100))
                        dx = -dx;
     
                    int param_y = y;
                    param_y += dy * vitesse;
     
                    if ((param_y > 440) || (param_y < 50))
                        dy = -dy;
     
                    x += dx * vitesse;
                    y += dy * vitesse;
     
                    maball.Location = new System.Drawing.Point(x, y);
                    Thread.Sleep(50);
                }
     
                //this.pictureBox1.Location = new System.Drawing.Point(100, 50);
                //this.pictureBox1.Location = new System.Drawing.Point(490, 440);
     
            }
        }
    }
    Merci

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2007
    Messages : 180
    Points : 198
    Points
    198
    Par défaut
    ça vient peut être du fait que tu utilises param pour tes 2 threads.

    Pour quelles raisons tu n'utilises pas une_ball et une_ball2 pour démarrer les threads ?

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Salut,

    Citation Envoyé par LoDev Voir le message
    ça vient peut être du fait que tu utilises param pour tes 2 threads.

    Pour quelles raisons tu n'utilises pas une_ball et une_ball2 pour démarrer les threads ?
    tout à fait.

    De plus, meme en modifiant cela, tu n'auras jamais qu'une seule balle qui bougera ici. En fait tes threads invokent la methode avancer sur le thread du controle, et cette methode etant une boucle sans fin, l'invoke ne retourne jamais. En fait ici, quand tu demarres ton premier thread, il invoke sa methode sur le thread d'UI et ca commence à mouliner, le deuxieme thread part, et il demande une invoke à son tour, le thread d'UI etant pris dans une boucle infini, l'invoke va etre mise en attente (bloqué) pour une durée egale à celle de la durée de la boucle infinie (soit infinie).

    Bref, pour avoir la bonne logique, il faut faire l'integralité de tes calculs sur le thread de la ball, pour ensuite n'invoker QUE le resultat final sur le thread d'UI.

    Pour reprendre ton 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
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
     
    namespace WindowsApplication1
    {
     
        public partial class Form1 : Form
        {
            ball une_ball;
            ball une_ball2;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                une_ball = new ball(100, 50);
                une_ball2 = new ball(400, 400);
                this.Controls.Add(une_ball.maball);
                this.Controls.Add(une_ball2.maball);
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Thread thr_lap1 = new Thread(new ThreadStart(une_ball.Avancer));
                thr_lap1.Start();
     
                Thread thr_lap2 = new Thread(new ThreadStart(une_ball2.Avancer));
                thr_lap2.Start();
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
            }
     
            static void Main()
            {
                Application.Run(new Form1());
            }
     
        }
     
        public class ball
        {
            public PictureBox maball;
     
            public ball(int x, int y)
            {
                maball = new System.Windows.Forms.PictureBox();
                maball.Image = SystemIcons.Application.ToBitmap();
                maball.Location = new System.Drawing.Point(x, y);
                maball.Name = "lol";
                maball.Size = new System.Drawing.Size(10, 10);
                maball.TabIndex = 0;
                maball.TabStop = false;
            }
     
     
            public PictureBox pict1 = new System.Windows.Forms.PictureBox();
            public PictureBox getpict1() { return pict1; }
     
            public void Avancer()
            {
                int x = maball.Location.X;
                int y = maball.Location.Y;
                //int x = this.pictureBox1.Location.X;
                //int y = this.pictureBox1.Location.Y;
                int dx = -1;
                int dy = -4;
                int vitesse = 5;
     
                Random Randomclass = new Random();
     
                for (; ; )
                {
                    int param_x = x;
                    param_x += dx * vitesse;
     
                    if ((param_x > 490) || (param_x < 100))
                        dx = -dx;
     
                    int param_y = y;
                    param_y += dy * vitesse;
     
                    if ((param_y > 440) || (param_y < 50))
                        dy = -dy;
     
                    x += dx * vitesse;
                    y += dy * vitesse;
     
                    maball.Invoke(new MethodInvoker(
                        delegate
                        {
                            maball.Location = new System.Drawing.Point(x, y);
                        }));
     
                    Thread.Sleep(50);
                }
     
                //this.pictureBox1.Location = new System.Drawing.Point(100, 50);
                //this.pictureBox1.Location = new System.Drawing.Point(490, 440);
     
            }
        }
    }
    Bon courage.

    Nota : Ton delegué TextBoxInvokeHandler etait inutile, il existe deja un type delegué de signature void (void) standard, c'est MethodInvoker. =)

  5. #5
    Membre habitué Avatar de Bobybx
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2005
    Messages : 122
    Points : 125
    Points
    125
    Par défaut
    Merci beaucoup pour cette réponse claire et constructive.

    Le programme me lance bien mes 2 threads maintenant.
    Bon, je vais m'attaquer à la communication entre threads pour que, lorsqu'il y ait une "collision" entre mes 2 picturebox, que la trajectoire soit modifiée.

    Merci en tout cas !!
    Je reviendrai dans le coin si mes threads ne veulent pas communiquer

  6. #6
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    salut

    si je peux juste me permettre une petite intervention

    Dans la mesure ou tu essayes de faire de l'animation, je ne te conseille pas
    trop d'avoir la gestion des animations de chaque objet à animer dans des threads séparés...

    Pourquoi ?

    En terme de performance, cela est plutot pas terrible et en plus, tu vas vite
    commencer à avoir des problèmes de communication inter thread, etc...

    En général (je viens du monde de la simulation (proche du jeu vidéo)), les
    architectures utilisés par les moteurs 3D sont plutots les suivants :

    Un thread qui s'occupe du rendu des objets (donc qui fait le Draw)
    Un thread qui s'occupe de la mise à jour des objets
    Un thread qui s'occupe eventuellement de récupérer des "ordres" venant
    du reseau et qui passe par un triple buffer pour échanger les données avec
    le thread de mise à jour des données

    Le principe de fonctionnement pourrait etre resumer à la boucle suivante:

    1 - Je recupere les infos thread reseau
    2 - Je mets à jour l'état de mes objets
    3 - Je dessine mes objets

    L'objectif est de laisser le thread de rendu des objets le plus consommateur possible pour avoir des performances d'affichage optimale... donc, moins de temps tu passes dans les mises à jour et plus tu peux dessiner (la, je me place plutot dans le cas d'un moteur 3D ...)

    Voila, c'était juste un "petit" conseil en passant

    The Monz, Toulouse

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

Discussions similaires

  1. problème débutant avenc les triggers
    Par yayooyayoo2005 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 11/01/2006, 11h52
  2. [VB.Net][Threading] Problème de parent ...
    Par maitrebn dans le forum Windows Forms
    Réponses: 3
    Dernier message: 03/01/2006, 11h05
  3. Thread problème pour l'arreter
    Par rvzip64 dans le forum Langage
    Réponses: 8
    Dernier message: 12/07/2005, 10h51
  4. [Thread]Problème de processus
    Par berg dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 18/06/2005, 20h40
  5. Thread--> problème avec ThreadProc
    Par stof dans le forum MFC
    Réponses: 33
    Dernier message: 08/06/2005, 13h47

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