Background Worker, la bonne solution ? Car ne fonctionne pas

Résolu/Fermé
Raphy5959 Messages postés 2 Date d'inscription mercredi 19 octobre 2016 Statut Membre Dernière intervention 20 octobre 2016 - 19 oct. 2016 à 22:07
Raphy5959 Messages postés 2 Date d'inscription mercredi 19 octobre 2016 Statut Membre Dernière intervention 20 octobre 2016 - 20 oct. 2016 à 19:05
Bonjour :)

Je vous explique déjà le fonctionnement voulu, je travail en c# avec visual studio 2010 .NET 4.0

J'ai un Form1 principal, dans lequel j'ai certaine donnée, et j'ai un bouton "Valider" pour enregistrer des données, jusque là, rien de bien compliqué.

Là ou sa se complique, c'est que quand j'appuie sur le bouton valider, j'ai un texte qui s'inscrit "en attente"..., et je doit avoir une boucle (ou une tache...) qui se lance afin de vérifier toutes les 1 secondes que la fonction check() retourne TRUE, et que tant que cette fonction n'est pas à TRUE, le formulaire est en attente, il n'enregistre rien, et dès que la fonction est à TRUE, ca enregistre le formulaire, éventuellement dans ce formulaire je pourrai avoir un bouton pour annuler cette boucle de recherche...

Bon dans un premier temps j'ai essayé un simple while(check()) directement dans le Form1, évidemment cela gèle tout mon formulaire, mais bon je me devais d'essayer :p

J'ai donc vue qu'on pouvais utiliser un Background Worker, donc j'ai créé une class Background_Worker que j'appel quand j'appuie sur le bouton "Valider" de mon Form1, dans ce Background Worker je met ce qui va bien, mais là ou sa ne fonctionne pas, c'est dans la fonction bw_RunWorkerCompleted(), j’essaie d'appeler la fonction qui enregistre les données de mon Form1, par exemple

Form1.save();

ou encore

Form1 form = new Form1();
form.save();

Le problème, c'est que sa n'enregistre rien, en fait au lieu d'utiliser le Form1 d'origine, j'ai l'impression qu'il en créé un nouveau vide, et qu'il essais de l'enregistrer!

A savoir que je ne suis pas fermer à d'autre proposition si vous pensez qu'il y a une façon plus simple de faire qu'avec un Background Worker...

Je vous n'affiche pas le vrai code car il est énorme, je vous affiche plutôt un code pour comprendre facilement comment j'essais de m'y prendre

J'ai ajouté l'option needCheck, en fait quand je désactive cette fonction sa enregistre direct le formulaire, et ceci fonctionne bien.


Form1.cs

namespace TEST
{
    public partial class Form1 : Form
    {
        private void buttonValider_Click(object sender, RoutedEventArgs e)
        {
            if (needCheck)
                save1();
            else
                save3();
        }

        private void save1()
        {
            label1.text = "En attente de validation...";
            Background_Worker bw = new Background_Worker();
            bw.start();
        }

        public void save2()
        {
            /* Ici je fait certain traitement que je veux faire seulement quand needCheck est activé, puis je lance save3 pour enregistrer */
            save3();
        }
        private void save3()
        {
             /* Ici j'enregistre mes données */
        }
    }
}



Background_Worker.cs

namespace TEST
{
    class Background_Worker
    {
        private BackgroundWorker bw = new BackgroundWorker();

        public Page()
        {
            bw.WorkerReportsProgress = false;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }
        public void start(object sender, RoutedEventArgs e)
        {
            if (bw.IsBusy != true)
            {
                bw.RunWorkerAsync();
            }
        }
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            while(!check())
                Thread.Sleep(1000);
        }
        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Form1 form = new Form1();
            form.save2();
            
            /* Si ici je met un messageBox, elle s'affiche bien */
        }
    }
}



Voilà, j'espère m'avoir bien exprimé, car parfois je suis tellement dans le projet que j'ai l'impression d'être clair, alors que je ne le suis pas du tout :P

Merci d'avance pour la lecture, et éventuellement pour vos suggestions :D
A voir également:

2 réponses

Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
19 oct. 2016 à 23:09
Bonjour

ton problème n'a rien a voir avec le backgroundWorker.

       private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Form1 form = new Form1();// ici tu initialises une nouvelle instance de form1, c'est donc la méthode save de cette nouvelle instance qui va être exécutée et pas la méthode save de l'instance ou tu as tes données.

            form.save2();
            

        }


Un formulaire est un objet comme un autre, tu peux en initialiser autant que tu veux, après il faut parler avec la bonne instance.

Si tu gardes cette architecture, il faut soit que tu passes en paramètre à ta classe Background_Worker la référence du bon Form1, soit émettre un évènement auquel tu auras abonné Form1. Voir ici https://codes-sources.commentcamarche.net/faq/11107-interactions-entre-form-en-net-c-et-vb-net

Mais pour le coup, tu te compliques bien la vie.
Un backgroundworker pour tester un résultat toutes les secondes c'est un peu lourd (sauf si le traitement de check() prend plus d'une 1/2 seconde). Et quand bien même tu veux faire un thread à part, tu pouvais le laisser dans le Form pour le peu qu'il fait....

Mais même dans le Form, c'est encore trop, un simple timer suffit.
C'est un type d'objets (en winforms c'est un contrôle) qui va générer un évènement à un intervalle définit, une fois qu'on l'a mis en route (pour celui de winform je ne sais plus si c'est Tick, ou Elapsed à vérifier), la méthode que tu abonnes à cette événement sera donc exécutée de façon régulière et sans figer le rester de ton Form. Tu y mets un truc de ce type

      if (Check())
      {
             monTimer.Stop();//ou (Is)Enabled = false selon les timers
             save();
      }




0
Raphy5959 Messages postés 2 Date d'inscription mercredi 19 octobre 2016 Statut Membre Dernière intervention 20 octobre 2016
20 oct. 2016 à 19:05
Bonjour et merci pour ta réponse :)

Finalement j'ai copier/coller bon BW directement dans la même classe que mon form1, au moins je fait appel a la fonction directement en tapant simplement save2();

mais c'est vrai que cela semble beaucoup plus facile avec un timer! Je vais regarder ça car cela ferai du ménage dans mon code, et peut être également que sa consomme moins de ressource :)

Merci beaucoup pour ta réponse :)
0