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 :

Zone critique pour 2 threads


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de TrEiZe85
    Inscrit en
    Février 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Février 2007
    Messages : 82
    Par défaut Zone critique pour 2 threads
    Petite explication :

    J'ai une application WinForm qui permet de consulter et de modifier les données d'une BDD MySql. Cette base de donnée est mise a jour grace à l'importation journaliere d'un fichier XML. Jusqu'ici rien de bien sorcier !

    Je voudrais pouvoir afficher le contenu de la base de données cela pendant l'importation de mon fichier XML. J'ai donc créer deux threads :

    threadListemat => pour la partie importation XML
    threadAffichage => Pour la partie affichage

    Seul probleme lorsque j'execute le threadAffichage pendant l'execution du threadListemat des erreurs apparaissent dues à la lecture/ecriture simultanée dans ma base de données...

    Il faudrait donc que je puisse bloquer l'acces en lecture/ecriture à ma BDD à un seul et unique thread....

    J'ai tenté l'utilisation du lock(this) ainsi que la suspension de mon thread (thread.Suspend())

    Comment empecher mon threadAffichage d'acceder à cette zone critique MySql en meme temps que le threadListemat ????

    Si vous voulez plus de precision ou des morceaux de mon code n'hesitez pas à demander !!!

    Merci de vos futures reponses !

  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
    Quand tu dis que tu as tenté d'utiliser le lock, pourrais-tu préciser ?

    Comment as-tu procédé et qu'est ce qui n'allait pas ? Car à priori ca n'a pas fonctionné

  3. #3
    Membre éclairé Avatar de TrEiZe85
    Inscrit en
    Février 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Février 2007
    Messages : 82
    Par défaut
    J'ai fait un lock(this) qui englobe les methodes d'acces a la BDD...

    Faut il que je lock toute ma classe ??? Est ce possible ???

    Merci de ta rep

  4. #4
    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
    Le lock(this) est a éviter en général. Il est plutôt conseillé de déclarer une variable privée pour ca, statique ou non, suivant que la zone critique soit valable pour une seule ou plusieurs instances.

    Un exemple comme un autre de l'utilisation du lock
    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
    class ClassTestThread
    {
        private static object verrou = new object();
     
        private string _texte;
        private AutoResetEvent _reset;
     
        public ClassTestThread(string texte, AutoResetEvent reset)
        {
            _texte = texte;
            _reset = reset;
        }
     
        public void Start()
        {
            ThreadPool.QueueUserWorkItem(Traitement);
        }
     
        private void Traitement(object state)
        {
            lock (verrou)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(_texte + " : " + i);
                    Thread.Sleep(new Random().Next(100, 2000));
                }
            }
     
            _reset.Set();
        }
    }
    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
    class Program
    {
        static void Main(string[] args)
        {
            AutoResetEvent[] resets = new AutoResetEvent[] { new AutoResetEvent(false), new AutoResetEvent(false) };
     
            ClassTestThread test1 = new ClassTestThread("Thread 1", resets[0]);
            ClassTestThread test2 = new ClassTestThread("Thread 2", resets[1]);
     
            test1.Start();
            test2.Start();
     
            WaitHandle.WaitAll(resets);
     
            Console.ReadLine();
        }
    }
    Si jamais tu utilisais lock(this) dans ce cas, le comportement ne serait plus celui attendu, à savoir que rien ne garanti que le premier thread ai fini avant que le second ne commence l'affichage.

  5. #5
    Membre éclairé Avatar de TrEiZe85
    Inscrit en
    Février 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Février 2007
    Messages : 82
    Par défaut
    Merci de ta reponse

    De mon coté je n'utilise pas une classe Thread comme ClassTestThread dans ton exemple....

    Voici une partie de mon code :

    Chargement de mon IHM et creation des threads
    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
     
    private void Form1_Load(object sender, EventArgs e)
            {
                dataGridView1.DataSource = null;
                DataSetBDD.Clear();
                dataGridView1.AutoGenerateColumns = false;
     
                monThread = new Thread(new ThreadStart(démarrageServeur));
                threadListemat=new Thread(new ThreadStart(importXml));
                threadProgressBar=new Thread(new ThreadStart(progressBar));
                threadProgressBarStart=new Thread(new ThreadStart(progressBarStart));
                threadAffichage=new Thread(new ThreadStart(affichageBDD));            
     
                monThread.IsBackground = true;
    			threadProgressBar.IsBackground = true;
                threadListemat.IsBackground = true;  
                threadProgressBarStart.IsBackground = true;
    			threadAffichage.IsBackground = true;
     
    			monThread.Start();
    			threadAffichage.Start();
                dataGridView1.Visible = true;
            }
    Code executé par le thread listemat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            private void importXml()
            {         
                this.Invoke(new setTexteStatusBarre(texteStatusBarre), "Etat : Verification fichier listemat.XML");
                gestionExcel.importerFichierXML("listemat.xml");
                this.Invoke(new setTexteStatusBarre(texteStatusBarre), "Etat : Xml importé");
                threadListemat.Abort();
            }
    Code executé par le thread affichage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        public void affichageBDD()
            {        	
            	while(gestionBDD.getEtatConnection()=="Open")
            	{
            	}
            	this.Invoke(new setAffichage(gestionBDD.affichageBDD),"*","");
            	threadAffichage.Abort();
            }
    methode contenant la zone critique :
    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
     
           public void insertionBDD(string requeteInsert)
            {
                this.requeteInsert = requeteInsert;
     
                connexionBDD();
     
                MySqlCommand Insert = new MySqlCommand(requeteInsert, Connection);
     
                lock(this)
                {          	
                    try
                	{
                    	Insert.ExecuteNonQuery();
                	}
                	catch (MySqlException e)
                	{
                    	MessageBox.Show(e.Message);                
                	}
    			}
                deconnexionBDD();
     
            }

    Je veut donc que le thread affichage s'execute seulement lorsque le thread listemat ne communique pas avec ma base....

  6. #6
    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
    En fait les threads en question ne tournent pas en "boucle", ils ne s'exécutent qu'une seule fois chacun, on peut faire plus simple en bloquant le second thread tant que le premier n'a pas fini à ce moment, ca devrait suffir, sauf si il y a autre chose derrière dont tu n'as pas parlé ^^

    Dans cet exemple, le thread d'affichage ne pourra démarrer qu'une fois celui de l'import terminé.
    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
    public partial class Form1 : Form
    {
        private AutoResetEvent _resetEvent;
     
        public Form1()
        {
            InitializeComponent();
     
            _resetEvent = new AutoResetEvent(false);
        }
     
        private void Form1_Load(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(Affichage);
            ThreadPool.QueueUserWorkItem(Import);
        }
     
        private void Import(object state)
        {
            // Traitement d'import
            MessageBox.Show("Import en cours ...");
            // On signale l'événement pour débloquer le thread d'affichage
            _resetEvent.Set();
        }
     
        private void Affichage(object state)
        {
            // Attends la fin du thread d'import
            _resetEvent.WaitOne();
            // Traitement de l'affichage
            MessageBox.Show("Affichage en cours ...");
        }
    }

Discussions similaires

  1. Aide pour un thread (debutant)
    Par koolkris dans le forum Delphi
    Réponses: 2
    Dernier message: 02/04/2007, 19h45
  2. Je n'arrive pas à faire sans stop() pour un thread
    Par PaladinFr dans le forum Concurrence et multi-thread
    Réponses: 2
    Dernier message: 15/03/2007, 14h37
  3. Critiques pour livre
    Par aure-sky dans le forum Flash
    Réponses: 1
    Dernier message: 03/02/2007, 23h22
  4. Librairie OO et portable pour RegExp, Thread, Sockets, etc..
    Par Swoög dans le forum Bibliothèques
    Réponses: 29
    Dernier message: 27/05/2006, 12h29

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