none
BackgroundWorker et lui demander d'attendre ? RRS feed

  • Question

  • Bonjour a tous


    Y a t'il un moyen de demander au BackgroundWorker d'attendre avant de poursuivre le reste du code ?

    Exemple :

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Console.WriteLine("toto")
    BackgroundWorker1.RunWorkerAsync()
    Console.WriteLine("titi")
    End Sub


    Dans cette exemple j'aimerais donc afficher toto d'attendre le BackgroundWorker qui finisse son boulot au bout des 30 secondes, et apres affiche titi mais apres les 30 secondes sans figé la formWindows

    J'ai bien trouvé IsBusy dans l'ojet BackgroundWorker mais cela fait figé la formWindows




    Cordialement, Troxsa
    mercredi 27 janvier 2010 15:02
    Auteur de réponse

Réponses

  • Bonjour Thomas

    Je pense avoir trouvé mon problème mais avant je vais expliquer tout ça pour bien que vous comprenez le problème de base

    Dans l'exemple de code que je viens de donné représente plus ou moins le code que j'ai donné plus haut

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Console.WriteLine("Connexion en cours")
            BackgroundWorker1.RunWorkerAsync()
            Console.WriteLine("Connexion établie")
    
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            While True
                Dim AttenteConnexion As String = "Exemple d'Attente d'une Connexion"
                If AttenteConnexion = "OK" Then
                    Exit While
                End If
            End While
        End Sub
    Ont est bien d'accord que ce code ne fonctionne pas en état actuel car boucle infini, c'est juste pour donner un exemple  ^^

    Donc dans cette exemple on vois bien que j'affiche dans la console "Connexion en cours" puis toute suite apres le BackgroundWorker qui doit attendre que la connexion ce face, puis quand cette connexion est faite il termine le BackgroundWorker et affiche "Connexion établie"
    Mais dans le cas du code cela ne ce passe pas du tout comme ça
    Le BackgroundWorker est immédiatement lancé et affiche toute suite "Connexion établie" que ce n'est pas le cas

    j'ai donc par la suite fait un truc dans ce style qui na pas du tout fait l'effet escompter

    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Console.WriteLine("Connexion en cours")
            BackgroundWorker1.RunWorkerAsync()
    
            While BackgroundWorker1.IsBusy = True
                Threading.Thread.Sleep(2000)
            End While
            Console.WriteLine("Connexion établie")
    
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            While True
                Dim AttenteConnexion As String = "Exemple d'Attente d'une Connexion"
                If AttenteConnexion = "OK" Then
                    Exit While
                End If
            End While
        End Sub
    End Class

    Ce code a fonctionner mais cela figeait la form
    après plusieurs essaie et quelle que recherche supplémentaire (MSDN, google code) j'ai fini par trouvé le fameux Application.DoEvents que je connais mais que je pensait pas pouvoir utiliser dans un BackgroundWorker pour je ne sais pas quelle raison :) des fois les solutions les plus bêtes sont les bonnes :P

    Donc le bloque While change de pas grand chose

            While BackgroundWorker1.IsBusy = True
                Application.DoEvents()
            End While

    Et dans ce cas la form n'est pas bloqué, l'attente de connexion ce passe tres bien, puis quand le BackgroundWorker est fini il affiche bien le message "Connexion établie"

    J'espère avoir été plus clair dans mes explications cette fois :)

    Merci pour tes propositions

    A bientot





























    Cordialement, Troxsa
    • Marqué comme réponse TroxsaEditor mercredi 27 janvier 2010 22:54
    mercredi 27 janvier 2010 22:50
    Auteur de réponse
  • Bonjour Troxsa,

    En effet, c'est plus clair, mais soit il y a quelque chose que je ne comprends pas vraiment encore, soit tu t'es un peu compliqué la tâche.
    Pourquoi ne pas avoir fait quelque chose du genre :

    Public Class Form1
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Console.WriteLine("Connexion en cours")
            BackgroundWorker1.RunWorkerAsync()
        End Sub
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            While True
                Dim AttenteConnexion As String = "Exemple d'Attente d'une Connexion"
                If AttenteConnexion = "OK" Then
                    Exit While
                End If
            End While
        End Sub
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            Console.WriteLine("Connexion établie")
        End Sub
    End Class


    Ici lorsque le BGW a récupéré la connexion, il marque de lui-même "Connexion établie" dans la Console, et ton thread principal continue de fonctionner pendant ce temps-là, il n'est pas figé.
    Et ça t'evite la boucle While dans le  thread principal, non ?

    Cordialement,

    Thomas


    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    • Marqué comme réponse TroxsaEditor jeudi 28 janvier 2010 09:25
    jeudi 28 janvier 2010 08:14

Toutes les réponses

  • Bonjour Troxsa,

    Je ne comprends pas bien la question.
    Alors je fais des propositions, suivant ce que j'en comprends.

    Proposition 1 :

    Une fois que le BGW a fini son traitement, il doit afficher Titi.
    Quand le BGW a fini son traitement, il lance l'évenement RunWorkerCompleted.
    Il te suffit de mettre ton code la-dedans.
    Et une fois le boulot fini, le BGW effectuera cette action.


    Proposition 2 :

    Il faut que tu lances ton traitement dans ton BGW, et que 30 secondes après avoir cliqué sur le bouton, que cela affiche titi ?
    Si c'est le cas, t'as qu'a lancer un 2eme BGW qui a un timer de 30 secondes, et qui affiche Titi quand il a fini, toujours avec l'évenement RunWorkerCompleted.


    Proposition 3 :

    Si jamais il faut que titi apparaisse soit après 30 secondes si le BGW a fini le boulot avant ou bien quand le BGW a fini le boulot s'il a pris plus de 30 secondes.
    Dans ton BGW, au debut, tu prends le DataTime.Now et tu le sauves dans une variable.
    Une fois le traitement fini, tu reprends cette variable, si DateTime.Now - TaVariable > 30 secondes, afficher Titi, sinon, faire un timer de ( 30 - DateTime.Now + TaVariable), et afficher Titi.


    Proposition 4 :
    J'ai vraiment rien pigé, chose tout à fait possible, et dans ce cas j'espere que tu vas éclairer ma lanterne ;)

    En espérant que cela t'aide,

    Thomas
    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    mercredi 27 janvier 2010 15:12
  • Bonjour Thomas

    Je pense avoir trouvé mon problème mais avant je vais expliquer tout ça pour bien que vous comprenez le problème de base

    Dans l'exemple de code que je viens de donné représente plus ou moins le code que j'ai donné plus haut

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Console.WriteLine("Connexion en cours")
            BackgroundWorker1.RunWorkerAsync()
            Console.WriteLine("Connexion établie")
    
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            While True
                Dim AttenteConnexion As String = "Exemple d'Attente d'une Connexion"
                If AttenteConnexion = "OK" Then
                    Exit While
                End If
            End While
        End Sub
    Ont est bien d'accord que ce code ne fonctionne pas en état actuel car boucle infini, c'est juste pour donner un exemple  ^^

    Donc dans cette exemple on vois bien que j'affiche dans la console "Connexion en cours" puis toute suite apres le BackgroundWorker qui doit attendre que la connexion ce face, puis quand cette connexion est faite il termine le BackgroundWorker et affiche "Connexion établie"
    Mais dans le cas du code cela ne ce passe pas du tout comme ça
    Le BackgroundWorker est immédiatement lancé et affiche toute suite "Connexion établie" que ce n'est pas le cas

    j'ai donc par la suite fait un truc dans ce style qui na pas du tout fait l'effet escompter

    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Console.WriteLine("Connexion en cours")
            BackgroundWorker1.RunWorkerAsync()
    
            While BackgroundWorker1.IsBusy = True
                Threading.Thread.Sleep(2000)
            End While
            Console.WriteLine("Connexion établie")
    
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            While True
                Dim AttenteConnexion As String = "Exemple d'Attente d'une Connexion"
                If AttenteConnexion = "OK" Then
                    Exit While
                End If
            End While
        End Sub
    End Class

    Ce code a fonctionner mais cela figeait la form
    après plusieurs essaie et quelle que recherche supplémentaire (MSDN, google code) j'ai fini par trouvé le fameux Application.DoEvents que je connais mais que je pensait pas pouvoir utiliser dans un BackgroundWorker pour je ne sais pas quelle raison :) des fois les solutions les plus bêtes sont les bonnes :P

    Donc le bloque While change de pas grand chose

            While BackgroundWorker1.IsBusy = True
                Application.DoEvents()
            End While

    Et dans ce cas la form n'est pas bloqué, l'attente de connexion ce passe tres bien, puis quand le BackgroundWorker est fini il affiche bien le message "Connexion établie"

    J'espère avoir été plus clair dans mes explications cette fois :)

    Merci pour tes propositions

    A bientot





























    Cordialement, Troxsa
    • Marqué comme réponse TroxsaEditor mercredi 27 janvier 2010 22:54
    mercredi 27 janvier 2010 22:50
    Auteur de réponse
  • Bonjour Troxsa,

    En effet, c'est plus clair, mais soit il y a quelque chose que je ne comprends pas vraiment encore, soit tu t'es un peu compliqué la tâche.
    Pourquoi ne pas avoir fait quelque chose du genre :

    Public Class Form1
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Console.WriteLine("Connexion en cours")
            BackgroundWorker1.RunWorkerAsync()
        End Sub
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            While True
                Dim AttenteConnexion As String = "Exemple d'Attente d'une Connexion"
                If AttenteConnexion = "OK" Then
                    Exit While
                End If
            End While
        End Sub
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            Console.WriteLine("Connexion établie")
        End Sub
    End Class


    Ici lorsque le BGW a récupéré la connexion, il marque de lui-même "Connexion établie" dans la Console, et ton thread principal continue de fonctionner pendant ce temps-là, il n'est pas figé.
    Et ça t'evite la boucle While dans le  thread principal, non ?

    Cordialement,

    Thomas


    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    • Marqué comme réponse TroxsaEditor jeudi 28 janvier 2010 09:25
    jeudi 28 janvier 2010 08:14
  • Bonjour,


    Et oui ... c'est vraiment bête de ne pas avoir pensé a ça avant lol, vivement les vacances :)

    Merci :)

    Cordialement, Troxsa
    jeudi 28 janvier 2010 09:27
    Auteur de réponse