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 :

besoin d'aide sur les thread


Sujet :

Windows Forms

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Points : 7
    Points
    7
    Par défaut besoin d'aide sur les thread
    Bonjour à tous,

    Voilà, je cherche à développer une espèce de fausse bombe (je précise que c'est pour un jeu).
    J'ai déjà réussi à la faire, mais en web, il s'agit d'une page web en local avec beaucoup de javascript.
    Dans le but de la faire évoluer, j'essai de la faire en tant que logiciel.

    Le problème que se pose est le suivant:
    Le compte à rebour doit être affiché et est rafraichi toutes les milisecondes (par exemple). Mais en même temps, l'utilisateur doit pouvoir entrer un code pour stopper le chrono.


    Ayant déjà pas mal cherché sur le net, j'en ai appris pas mal sur les thread, car je dois en faire une si je veux pouvoir travailler avec le chrono sans faire planter l'application. Le problème est que je n'y arrive pas...

    afin de pouvoir interagir avec le chrono, j'ai créé une classe Countdown qui me sert à faire tout le traitement du temps. Elle sera utilisée dans une thread...

    Serait-il possible d'avoir quelques explications sur comment afficher le temps restant (calculé dans la classe Countdown) provenant d'une Thread ?

    je place ici mon code, histoire de voir s'il n'y a pas une meilleur solution:
    Code principal : 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
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
     
    namespace bombe
    {
        public partial class Form1 : Form
        {
     
            Random rndNumber;
            bool randomed = false;
            Countdown chrono;
            Thread t;
            int nbCode = 0;
     
            public Form1()
            {
                InitializeComponent();
     
                //mise en fullscreen
                this.FormBorderStyle = FormBorderStyle.None;
                this.WindowState = FormWindowState.Maximized;
     
                //création du chrono et création du Thread
                chrono = new Countdown(1, 0, 0);
                t = new Thread(new ThreadStart(chrono.chrono));
                t.Start();
     
     
                //affichage du code de désamorçage
                tbCodeAEntrer.Text = random();
            }
     
            //petite fonction générant un nombre aléatoire
            public String random()
            {
                if (randomed == false)
                {
                    rndNumber = new Random();
                    randomed = true;
                }
                return rndNumber.Next(1, 100).ToString();
            }
     
            //contrôle du code à entrer et du code entré
            private void btnValider_Click(object sender, EventArgs e)
            {
                //si c'est correct et qu'il n'y a pas eu 3 code entrés
                if (tbCodeAEntrer.Text == tbCodeEntre.Text && nbCode < 3)
                {
                    tbCodeAEntrer.Text = random();
                    tbCodeEntre.Text = "";
                    nbCode++;
                }
            }
     
            //affichage du temps
            private void btnTestChrono_Click(object sender, EventArgs e)
            {
                tbTestChrono.Text = chrono.getMin() + " " + chrono.getSec() + " " + chrono.getMili();
                Thread.Sleep(1);
                chrono.chrono();
            }
        }
    }
    Code Countdown : 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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace bombe
    {
        class Countdown
        {
            //attributs
            private int min;
            private int sec;
            private int mili;
     
            //constructeur
            public Countdown(int min, int sec, int mili)
            {
                this.min = min;
                this.sec = sec;
                this.mili = mili;
            }
     
            //setters
            public void setMin(int min)
            {
                this.min = min;
            }
            public void setSec(int sec)
            {
                this.sec = sec;
            }
            public void setMili(int mili)
            {
                this.mili = mili;
            }
     
            //getters
            public int getMin()
            {
                return this.min;
            }
            public int getSec()
            {
                return this.sec;
            }
            public int getMili()
            {
                return this.mili;
            }
     
            //méthodes
            public void chrono()
            {
                mili--;
                if (mili < 0)
                {
                    mili = 9;
                    sec--;
                }
                if (sec < 0)
                {
                    sec = 59;
                    mili = 9;
                    min--;
                }
                if (min < 0)
                {
                    mili = 0;
                    sec = 0;
                    min = 0;
                }
            }
        }
    }

    pour le moment, le rafraichissement du temps se fait à chaque clic sur le bouton btnTestChrono... je n'arrive pas à le faire dans une boucle sant tout faire freezer...

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

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

    Plutôt qu'essayer de te lancer dans les thread (pas facile à gérer quand on n'en a pas l'habitude), tu devrais regarder du coté de la class Timer qui permet de faire ce que tu veux (soit appeler une méthode à chaque fois qu'une durée déterminé s'est écoulée).

    Sinon, pour garder ton thread en vie, il faut mieux mettre une boucle dans ta méthode d'entrée (ici chrono) car la il fait un calcul puis ton thread s'arrête.
    Ensuite, il est préférable que le thread rafraichisse de lui même l'affichage (en lui passant un delgate vers une fonction de ton form par exemple) plutôt que ce soit le form qui interroge le thread pour avoir l'information.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    311
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 311
    Points : 337
    Points
    337
    Par défaut
    Le backgroundworker peut être utile aussi

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Points : 7
    Points
    7
    Par défaut
    merci pour ta réponse

    concernant le fait de tout faire en une fois, j'y avais déjà pensé mais il y a deux problèmes...
    1) comme la page sera rafraichie tout les milièmes, il sera impossible d'écrire le code de désamorçage...
    2) tant que la boucle ne sera pas finie, le programme sera complètement bloqué... c'est pourquoi je comptais faire ce travail dans une thread


    par contre, j'avais pas pensé à rafraichir la page via la thread...
    je vais creuser de ce côté

    merci

  5. #5
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    avec un timer réglé à 20ms (en dessous ca sert à rien) tu peut mettre à jour le temps restant sur l'interface
    vu que c'est un logiciel et pas une page web, y a pas vraiment de rafraichissement à faire, et puis c'est rapide, donc l'utilisateur peut rentrer un nombre dans un textbox en meme temps

    un thread pour rafrachir l'interface utilisateur aussi rapide n'engendrera que des ralentissements pour passer d'un thread à l'autre ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Points : 7
    Points
    7
    Par défaut
    je suis vraiment désolé de demander ça mais...

    serait-il possible d'avoir un exemple ??
    tout ce que je trouve, c'est en console et ça affiche tu texte toutes les x ms mais on ne peut rien faire pendant ce temps...

    je ne demande pas un super code, juste quelques lignes qui permettent de faire tourner un un timer affichant le temps d'un côté sans bloquer l'utilisateur...


    désolé de demander ça...
    j'ai pas l'habitude de passer des journées sur un même problème...

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    poser un timer sur le form
    régler l'interval à 20
    mettre enabled à true (démarrera le timer au lancement de l'appli)
    poser un label sur le form
    poser un textbox sur le form

    déclarer une variable temps de type decimal qui vaut 10 par exemple (le nombre de secondes)

    sur l'évènement tick du timer décrémenter temps de 0,02 et mettre le temps dans le label


    le résultat normalement c'est que le label affiche le compte à rebours et le textbox est utilisable (voir si les calculs sont bons quand meme , et si le timer n'arrive pas à suivre, alors il faudra enregistrer la date de départ plutot que de décrémenter un decimal, ca sera plus juste)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Points : 7
    Points
    7
    Par défaut
    merci beaucoup,


    je vais essayer tout de suite

    encore merci


    edit: OUIIIIIIIIIIIIII !!!!
    ça marche !!!!
    merci, merci, merci, merci !!!

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Points : 7
    Points
    7
    Par défaut
    si jamais, je pose ici le code que j'ai fais, si un jour quelqu'un en a besoin...

    donc, pour information, il s'agit d'ue code pour faire une fausse bombe...
    on l'utilise en airsoft, sur un ordi portable pourri qu'on a bien protégé.

    le principe:
    • l'équipe des terroristes va poser l'ordi et choisi la durée (30 ou 60 minutes)
    • durant le première minutes, l'équipe des terroristes va se cacher
    • au changement de bip, l'équipe des démineurs entre en action
    • pour désamorcer la bombe, il faut entrer 3 codes de désactivations qui seront affichés, dans les temps...


    evidemment, l'interface est... comment dire... assez vide, étant donné que c'est la première version... Au moins, chacun peut gérer l'apparence à sa guise...


    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
    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
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Media;
     
    namespace test
    {
        public partial class Form1 : Form
        {
            Timer t;
            double min;
            double sec;
            double mili;
     
            Random rndNumber;
     
            int etat = 0;   //etat = 1 => réussi / etat = 2 => raté
            int nbCode = 1;
            double minDepart;
     
     
            public Form1()
            {
                InitializeComponent();
     
                //mise en fullscreen
                this.FormBorderStyle = FormBorderStyle.None;
                this.WindowState = FormWindowState.Maximized;
     
                //timer
                t = new Timer();
                t.Interval = 90;
                t.Tick += new EventHandler(boucle);
     
     
                //code aléatoire à entrer
                rndNumber = new Random();
                tbCodeAEntrer.Text = nbAleatoire();
            }
     
     
            //FONCTIONS
     
            //choix de la durée du timer: 30 minutes
            private void btn30min_Click(object sender, EventArgs e)
            {
                min = 30;
                hide();
            }
            //choix de la durée du timer: 60 minutes
            private void btn60min_Click(object sender, EventArgs e)
            {
                min = 60;
                hide();
            }
            public void hide()
            {
                sec = 0;
                mili = 0;
                btn30min.Visible = false;
                btn60min.Visible = false;
                tbCodeAEntrer.Visible = true;
                tbCodeEntre.Visible = true;
                t.Enabled = true;
                couleur(Color.White);
                tbCodeEntre.Enabled = true;
                tbCodeEntre.Text = "";
                lbCommentaire.Text = "";
                tbCodeAEntrer.Text = nbAleatoire();
                tbCodeEntre.Focus();
                minDepart = min;
                nbCode = 1;
            }
     
            //retourne un code aléatoire à 9 chiffres
            public String nbAleatoire()
            {
                return rndNumber.Next(100000000, 999999999).ToString();
            }
     
            //fonction appelée en boucle par le timer
            public void boucle(object obj, EventArgs ea)
            {
                //traitement du temps
                mili--;
                if (mili < 0)
                {
                    mili = 9;
                    sec--;
                }
                if (sec < 0)
                {
                    sec = 59;
                    mili = 9;
                    min--;
                }
                if (min < 0)
                {
                    mili = 0;
                    sec = 0;
                    min = 0;
     
                    etat = 2;
                    traitement();
                }
     
                //BIPS ÉMIS PAR LE CHRONO
     
                //durant le minute de mise en position
                if (min == minDepart - 1)
                {
                    if (sec % 1 == 0 && mili == 0)
                    {
                        //durant la minute
                        if (sec != 0)
                        {
                            PlayWAV("audio/start.wav");
                        }
                        //fin de la minute
                        else
                        {
                            PlayWAV("audio/1min.wav");
                        }
                    }
                }
     
                //durant la partie
                else if (min > 1)
                {
                    if (sec % 5 == 0 && mili == 0)
                    {
                        PlayWAV("audio/temps.wav");
                    }
                }
     
     
                //dernière minute
                else
                {
                    //de 1 min à 30sec
                    if (min <= 1 && sec > 30 && sec % 1 == 0 && mili == 0)
                    {
                        PlayWAV("audio/1min.wav");
                    }
                    //de 30sec à 5 sec
                    else if (sec <= 30 && sec > 5 && mili == 0)
                    {
                        PlayWAV("audio/30sec.wav");
                    }
                    //de 5sec à 0sec
                    else if (sec <= 5 && mili % 5 == 0 && (sec + mili != 0))
                    {
                        PlayWAV("audio/5sec.wav");
                    }
               }
     
                //affichage du chrono
                lbTemps.Text = min + " : " + sec + " : " + mili;
            }
     
            //lors de l'appui sur la touche enter dans le textbox où on rentre le code
            private void tbCodeEntre_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    //masque le bip émis
                    e.SuppressKeyPress = true;
     
                    //si le code est juste et que ce n'est pas le 3ème code
                    if (tbCodeAEntrer.Text == tbCodeEntre.Text && nbCode < 3)
                    {
                        nbCode++;
                        tbCodeAEntrer.Text = nbAleatoire();
                        tbCodeEntre.Text = "";
                    }
                    //si le code est juste et c'est le 3ème code
                    else if (tbCodeAEntrer.Text == tbCodeEntre.Text && nbCode == 3)
                    {
                        etat = 1;
                        traitement();
                    }
                    //si le code est faux
                    else if (tbCodeAEntrer.Text != tbCodeEntre.Text)
                    {
                        etat = 2;
                        traitement();
                    }
                }
            }
     
            //IA du programme
            public void traitement()
            {
                switch (etat)
                {
                    //partie en cours
                    case 0:
                        break;
     
                    //partie finie => réussi
                    case 1:
                        t.Stop();
                        lbCommentaire.Text = "réussi";
                        PlayWAV("audio/win.wav");
                        couleur(Color.Green);
                        tbCodeEntre.Enabled = false;
                        btn30min.Visible = true;
                        btn60min.Visible = true;
                        break;
     
                    //partie finie => perdu
                    case 2:
                        t.Stop();
                        lbCommentaire.Text = "perdu";
                        PlayWAV("audio/end.wav");
                        couleur(Color.Red);
                        tbCodeEntre.Enabled = false;
                        btn30min.Visible = true;
                        btn60min.Visible = true;
                        break;
                    default:
                        break;
                }
            }
     
            //change la couleur des objets présents sur la page
            public void couleur(Color couleur)
            {
                lbCommentaire.ForeColor = couleur;
                lbTemps.ForeColor = couleur;
            }
     
            //joue les sons
            public static void PlayWAV(String Location)
            {
                SoundPlayer player = new SoundPlayer(Location);
                player.Play();
            }
        }
    }
    Pour info, les bips émis sont dans un dossier "audio" et sont en .WAV


    Encore merci pour le coup de main




    demonofshadow

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

Discussions similaires

  1. Aide sur les Threads
    Par themoye dans le forum MFC
    Réponses: 24
    Dernier message: 06/03/2005, 15h02
  2. Besoin d'aide sur les fonction d'interbase
    Par BOUBOU81 dans le forum InterBase
    Réponses: 2
    Dernier message: 05/11/2004, 10h00
  3. besoin d'aide sur les ORB
    Par floorfille dans le forum CORBA
    Réponses: 4
    Dernier message: 24/08/2004, 15h43
  4. Filemaker ... besoin d'aide sur les Plugin
    Par joange dans le forum Autres SGBD
    Réponses: 3
    Dernier message: 22/04/2004, 10h16
  5. [CR] besoin d'aide sur les formules
    Par GuillaumeDSA dans le forum Formules
    Réponses: 4
    Dernier message: 10/07/2003, 12h19

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