Partage
  • Partager sur Facebook
  • Partager sur Twitter

Synchroniser une BDD à plusieurs applications C#

Synchroniser une Base de Données à plusieurs applications en C#

    16 janvier 2019 à 12:20:57

    Bonjour à toutes et à tous, 

    J'explique mon problème : 

    Je réalise une application en C# qui est relié à une base de données MySQL en Ligne. Pour l'instant j'ai pas de souci quand à la connexion, la lecture et l'écriture de données sur celle ci. 

    Cette application est installée sur plusieurs machines qui ont tous accès à cette base en lecture /écriture. il n'y a pas de hiérarchie, tout le monde peut lire et écrire.

    Pour la synchronisation des données, si la machine A fait une modification, la machine B doit d'abord appuyé sur le bouton " Actualiser " pour voir ces modifications dans un control Datagridview. 

    1 - Comment est ce que je peux faire pour automatiser ce rafraîchissement au niveau des applications clients sans qu'ils aient besoin de cliquer sur le bouton " Actualiser " pour que ces données soit actualisées dans la Datagrid.

    2- Est ce qu'il y a d'autres possibilités ou technologies me permettant de faire ceci. Et peut être que vous avez des conseils à me donner pour ce type de réalisations.

    Merci à vous pour vos réponses. 

    -
    Edité par marickbiokou 16 janvier 2019 à 12:25:11

    • Partager sur Facebook
    • Partager sur Twitter
      16 janvier 2019 à 13:06:03

      marickbiokou a écrit:

      Bonjour à toutes et à tous, 

      J'explique mon problème : 

      Je réalise une application en C# qui est relié à une base de données MySQL en Ligne. Pour l'instant j'ai pas de souci quand à la connexion, la lecture et l'écriture de données sur celle ci. 

      Cette application est installée sur plusieurs machines qui ont tous accès à cette base en lecture /écriture. il n'y a pas de hiérarchie, tout le monde peut lire et écrire.

      Pour la synchronisation des données, si la machine A fait une modification, la machine B doit d'abord appuyé sur le bouton " Actualiser " pour voir ces modifications dans un control Datagridview. 

      1 - Comment est ce que je peux faire pour automatiser ce rafraîchissement au niveau des applications clients sans qu'ils aient besoin de cliquer sur le bouton " Actualiser " pour que ces données soit actualisées dans la Datagrid.

      2- Est ce qu'il y a d'autres possibilités ou technologies me permettant de faire ceci. Et peut être que vous avez des conseils à me donner pour ce type de réalisations.

      Merci à vous pour vos réponses. 

      -
      Edité par marickbiokou il y a 37 minutes


      Bonjour,

      Il me semble que la méthode la plus facile serait de démarrer un while(true) dans un nouveau thread avec un mysqldatareader?

      A vérifier ^^

      • Partager sur Facebook
      • Partager sur Twitter
        16 janvier 2019 à 14:14:54

        Bonjour NextrieSH, Merci pour ta réponse rapide. Je vais creusé de ce coté la pour voir.

        Alors si je comprends bien,

        - Je dois créer un thread qui sera tout le temps exécuté même pendant l'utilisation de l'application( En tache de fond je suppose ).

        Est ce que ce thread permettrait justement que la machine B ait les données rafraîchies même pendant son utilisation, sans bien-sûr faire appel à l'action du bouton " Actualiser " pour récupérer les modifications et ce presque instantanément. Je dis peut être une bêtise, mais bon je veux être sûr.

        NextrieSH a écrit:

        Bonjour,

        Il me semble que la méthode la plus facile serait de démarrer un while(true) dans un nouveau thread avec un mysqldatareader?

        A vérifier ^^


        J'ai essayé de faire avec les Threads comme ceci mais j'ai au lancement du programme une erreur :

        voici ce que je fais :

        - Dans ma méthode Laod, j'ai :

         private void Form1_Load(object sender, EventArgs e)
                {
                    //Gestion du raffraichissement par le biais d'un Thread
                    Thread Mon_Thread_De_Synchronisation;
        
                    Mon_Thread_De_Synchronisation = new Thread(new ThreadStart(Raffraichir_Liste_des_Comptes));
        
                    Mon_Thread_De_Synchronisation.Start();
        
                }

        Ensuite dans ma méthode de rafraîchissement ceci  : 

                public void Raffraichir_Liste_des_Comptes()
                {
                    try
                    {
                        while (true)
                        {
                            ActualiserListeDesComptes();//Le code ci-dessus
                            Thread.Sleep(5000);
                        }
                    }
                    catch (Exception Ex)
                    {
                        MessageBox.Show(Ex.Message);
                    }
                }

        Merci à vous.

        -
        Edité par marickbiokou 16 janvier 2019 à 17:08:59

        • Partager sur Facebook
        • Partager sur Twitter
          16 janvier 2019 à 14:49:17

          Laissez les DataReader crever en paix.

          Le fait que les données affichées ne soit pas à jour, c'est pas un problème.

          Vous utilisez un Timer d'IHM, pour pas vous emmerdez avec la synchronisation entre thread, pour rafraichir régulièrement l'affichage.

          Le DataSet fera le travail de détection des accès concurrents tout seul, et le DataBinding propagera les mises à jours du DataSet automatiquement vers l'IHM.

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            16 janvier 2019 à 16:41:10

            bacelar a écrit:

            Laissez les DataReader crever en paix.

            Le fait que les données affichées ne soit pas à jour, c'est pas un problème.

            Vous utilisez un Timer d'IHM, pour pas vous emmerdez avec la synchronisation entre thread, pour rafraichir régulièrement l'affichage.

            Le DataSet fera le travail de détection des accès concurrents tout seul, et le DataBinding propagera les mises à jours du DataSet automatiquement vers l'IHM.


            Bonjour bacelar, Pour l'instant je n'utilise pas le DataBinding, mais uniquement les DataTable et les dataAdapter pour mes données. 

            Voici ce que je fais pour l'instant pour charger mes données depuis ma base MySQL : 

            private void ActualiserListeDesComptes()
                    {
            
                        DataTable MyDataTable = new DataTable();
                        try
                        {
                            MySQL_Connexion = MyCon.Connexion_MySql_BDD();
                            MySqlDataAdapter DataAdapter = new MySqlDataAdapter("SELECT * FROM Comptes_Connexions ORDER BY Site_Connexion ASC", MySQL_Connexion);
                            DataAdapter.Fill(MyDataTable);
            
                            this.dataGridView_Comptes_Connexions.DataSource = MyDataTable;
            
                            this.dataGridView_Comptes_Connexions.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                            this.dataGridView_Comptes_Connexions.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                            this.dataGridView_Comptes_Connexions.Columns[0].Visible = false;//Id_Comptes
                            this.dataGridView_Comptes_Connexions.AllowUserToResizeRows = false;
                            this.dataGridView_Comptes_Connexions.AllowUserToResizeColumns = false;
                            this.dataGridView_Comptes_Connexions.RowHeadersVisible = false;
            
                            MySQL_Connexion.Close();
            
                        }
                        catch (Exception Ex)
                        {
                            MessageBox.Show(Ex.ToString());
                        }
                    }

            Quand vous parlez de Timer d'IHM, est ce juste le Timer normal ? ou quelque chose d'autres ? 

            Merci.

            • Partager sur Facebook
            • Partager sur Twitter
              16 janvier 2019 à 17:34:57

              >Quand vous parlez de Timer d'IHM, est ce juste le Timer normal ?

              C'est quoi "normal" ??? C'est un timer qui utilise le thread de la bibliothèque graphique que vous utilisez (WinForm, WPF, etc...).

              Cela permet de ne pas galérer avec le multi-threading.

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                16 janvier 2019 à 18:04:47

                >C'est quoi "normal" ??? C'est un timer qui utilise le thread de la bibliothèque graphique que vous utilisez (WinForm, WPF, etc...).

                Je voulais simplement dire une utilisation normal d'un Timer.

                >Cela permet de ne pas galérer avec le multi-threading.

                Ok Merci, je chercherai de ce côté la et je vous tiens au courant de l'avancé. 

                • Partager sur Facebook
                • Partager sur Twitter
                  17 janvier 2019 à 8:00:35

                  Oui en effet pour l'opération interthread on doit généralement effectuer un gros détour pour que cela fonctionne.

                  Admettons que ton tableau ait 2 colonnes, nom et prénom je suivrais la méthode suivante : 

                  -> Créer une classe "x" comportant deux paramètres noms et prénoms

                  -> créer un objet de cette classe quand il y'a de nouvelles informations de la part du while(true) et l'ajouter a une liste

                  -> vérifier par un timer de tick 1 (~instantané) que le nombre d'élément dans la liste à changé 

                  -> ajouter au tableau etc..

                  Mais oui c'est une méthode que je trouve compliqué pour un résultat assez simple.

                  Je suis sur qu'il existe un meilleur moyen mais c'est la technique que j'utilise pour contourner les opérations inter-threads

                  • Partager sur Facebook
                  • Partager sur Twitter
                    17 janvier 2019 à 13:57:13

                    Je vais regardé ces différentes options, et je reviendrai faire un retour de la solution que j'ai adopté. Merci pour vos réponses ;)

                    -
                    Edité par marickbiokou 17 janvier 2019 à 18:20:28

                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 janvier 2019 à 9:07:03

                      C'est un peu usine à gaz votre machin.

                      Avoir un champ type concaténation de nom prénom, c'est le type de champ facilement stockable dans une colonne de type "calculée" dans une DataTable.

                      En vous servant de la DataTable comme source de DataBinding, les mises à jours de l'IHM se feront automatiquement avec les modifications de la DataTable.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        30 janvier 2019 à 9:10:22

                        Rebonjour tout le monde, 
                        Alors voici ce que j'ai pu faire avec aussi l'aide de MSDN. Cela Fonctionne. Peut être qu'il y a moyen de faire autrement, et / ou mieux optimiser le code, mais je pense avoir fait attention à ce dernier.
                        J'ai travaillé avec les " Timers " et les " Threads ".

                        Je mets la solution. Cela peut aider d'autres personnes ;-)

                        Dans ma forme principale contenant mon control Datagridview, j'ai : 

                        La Classe Form1 : 

                        public delegate void Raffraichissement();
                             public Raffraichissement myDelegate;
                             private Thread myThread;
                             private static System.Timers.Timer aTimer;
                         
                            class form1class
                            {
                                public form1class()
                                {
                                    InitializeComponent();
                                    Raffraichir_Liste_des_Comptes();// Méthodes de chargement de ma datagridview
                         
                                    myDelegate = new Raffraichissement(Raffraichir_Liste_des_Comptes);
                         
                                    SetTimer();
                                }
                         
                                private void ThreadFunction()
                                {
                                    MyThreadClass myThreadClassObject = new MyThreadClass(this);
                                    myThreadClassObject.Run();
                                }
                         
                                private void SetTimer()
                                {
                                    // Create a timer with a two second interval.
                                    aTimer = new System.Timers.Timer(10000);
                                    // Hook up the Elapsed event for the timer. 
                                    aTimer.Elapsed += Event_Lancer_Par_MonTimer;
                         
                                    aTimer.AutoReset = true;
                                    aTimer.Enabled = true;
                                }
                         
                                public void Event_Lancer_Par_MonTimer(Object source, ElapsedEventArgs e)
                                {         
                                    myThread = new Thread(new ThreadStart(ThreadFunction));
                                    myThread.Start();
                                }
                         
                        private void ActualiserListeDesComptes()
                                {
                         
                                    DataTable MyDataTable = new DataTable();
                                    try
                                    {
                                        MySQL_Connexion = MyCon.Connexion_MySql_BDD();
                                        MySqlDataAdapter DataAdapter = new MySqlDataAdapter("SELECT * FROM Comptes_Connexions ORDER BY Site_Connexion ASC", MySQL_Connexion);
                                        DataAdapter.Fill(MyDataTable);
                         
                                        this.dataGridView_Comptes_Connexions.DataSource = MyDataTable;
                         
                                        this.dataGridView_Comptes_Connexions.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                                        this.dataGridView_Comptes_Connexions.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                                        this.dataGridView_Comptes_Connexions.Columns[0].Visible = false;//Id_Comptes
                                        this.dataGridView_Comptes_Connexions.AllowUserToResizeRows = false;
                                        this.dataGridView_Comptes_Connexions.AllowUserToResizeColumns = false;
                                        this.dataGridView_Comptes_Connexions.RowHeadersVisible = false;
                         
                                        MySQL_Connexion.Close();
                         
                                    }
                                    catch (Exception Ex)
                                    {
                                        MessageBox.Show(Ex.ToString());
                                    }
                                }
                            }
                        
                        


                        La classe Gérant mon Thread :


                        class MyThreadClass
                            {
                                Form1 myFormControl1;
                                public MyThreadClass(Form1 myForm)
                                {
                                    myFormControl1 = myForm;
                                }
                         
                                public void Run()
                                {
                                    // Exécutez le délégué spécifié sur le thread qui possède le handle de fenêtre sous-jacente du contrôle 'myFormControl1'.
                                    myFormControl1.Invoke(myFormControl1.myDelegate);
                                }
                            }

                        Merci pour vos aides ;-) très appréciable. je sais ca arrive un peu tard, mais j'ai faire pas mal de choses entre deux. 

                        Peu être que cela pourrait etre mieux faites. mais pour l'instant c'est ce que j'ai pu faire.

                        bacelar a écrit:

                        C'est un peu usine à gaz votre machin.

                        Avoir un champ type concaténation de nom prénom, c'est le type de champ facilement stockable dans une colonne de type "calculée" dans une DataTable.

                        En vous servant de la DataTable comme source de DataBinding, les mises à jours de l'IHM se feront automatiquement avec les modifications de la DataTable.



                        Bacelar, je vais regardé de ce côté également et revenir vers toi.

                        Encore Merci

                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 janvier 2019 à 11:25:50

                          Code "pédagogiquement" correct.

                          Mais,

                          c'est assez lourd avec ces thread et delegate, l'utilisation de lambda expression et d'await/async serait plus concise et claire.

                          Couplage très fort entre les différents éléments, obligeant à tout reprendre en cas de modification de l'un des composants et gros difficulté pour utiliser l'un de ces composant dans un cadre légèrement différent.

                          Intrinsèquement, l'utilisation d'un Timer "static" rend votre solution complètement inopérante dans le cas où votre classe "Form1" n'est pas un Singleton.

                          D'un point de vue "économie de ressource machine", c'est vraiment pas ça (récupération de TOUTES les données sans réels motifs, affiché ou pas), et d'un point de vue réactivité de l'IHM, votre manière de faire la plombe. Car, même en utilisant des threads, c'est t toujours le thread d'IHM qui fait TOUT travail.

                          Donc, d'un point de vue Analyse/Conception, c'est vraiment pas ça. :(

                          Pour la mise en œuvre :

                          Manque l'utilisation de l'instruction "using" pour alléger et simplifier la gestion des ressources comme celles que l'on doit "closer".

                          On ne catch JAMAIS les exceptions de type "Exception". On ne catch que les exceptions que l'on sait gérer, et une pauvre MessageBox, c'est pas un traitement. Le comportement par défaut du système dans ce cas et largement plus pertinent que cette MessageBox des années 1970.

                          Il doit manquer un peu de code qui, je l'espère, doit avoir bien changé depuis vos premier posts, comme la méthode "Raffraichir_Liste_des_Comptes" et son horrible boucle active.

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                            17 février 2019 à 13:28:45

                            bacelar a écrit:

                            Code "pédagogiquement" correct.

                            Mais,

                            c'est assez lourd avec ces thread et delegate, l'utilisation de lambda expression et d'await/async serait plus concise et claire.

                            Couplage très fort entre les différents éléments, obligeant à tout reprendre en cas de modification de l'un des composants et gros difficulté pour utiliser l'un de ces composant dans un cadre légèrement différent.

                            Intrinsèquement, l'utilisation d'un Timer "static" rend votre solution complètement inopérante dans le cas où votre classe "Form1" n'est pas un Singleton.

                            D'un point de vue "économie de ressource machine", c'est vraiment pas ça (récupération de TOUTES les données sans réels motifs, affiché ou pas), et d'un point de vue réactivité de l'IHM, votre manière de faire la plombe. Car, même en utilisant des threads, c'est t toujours le thread d'IHM qui fait TOUT travail.

                            Donc, d'un point de vue Analyse/Conception, c'est vraiment pas ça. :(

                            Pour la mise en œuvre :

                            Manque l'utilisation de l'instruction "using" pour alléger et simplifier la gestion des ressources comme celles que l'on doit "closer".

                            On ne catch JAMAIS les exceptions de type "Exception". On ne catch que les exceptions que l'on sait gérer, et une pauvre MessageBox, c'est pas un traitement. Le comportement par défaut du système dans ce cas et largement plus pertinent que cette MessageBox des années 1970.

                            Il doit manquer un peu de code qui, je l'espère, doit avoir bien changé depuis vos premier posts, comme la méthode "Raffraichir_Liste_des_Comptes" et son horrible boucle active.

                            Merci pour votre remarque. Un travail conséquent est à faire sur ma méthode de travail et l'allègement du code. Je dois encore beaucoup travailler, mais j'y arriverai. Merci beaucoup pour votre aide. 

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Synchroniser une BDD à plusieurs applications C#

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown