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

VB.NET Discussion :

Arrêt du BackGroundWorker [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Apprentie
    Inscrit en
    Avril 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprentie

    Informations forums :
    Inscription : Avril 2016
    Messages : 18
    Par défaut Arrêt du BackGroundWorker
    Bonjour à tous,

    j'ai cherché des solutions à mon problème, mais elles ne me semble pas adaptées.


    L'envoie de 2Ko de données sur le SerialPort étant lourd, j'ai décidé de faire un BGW pour garder la main sur l'application. J'enverrai les données puis attendrais que l'on demande l'arrêt du BGW. (J'ai testé de mettre la commande d'arrêt dans un RunWorkerCompleted, mais ça ne marche pas..)
    Seulement, je coince à l'arrêt du BGW :

    Dans mon thread principal, j'ai codé quelques lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
               For i = 1 To 2
                       FlagBGK = False
                       If BackgroundWorker1.IsBusy Then
                           BackgroundWorker1.CancelAsync()
                           BackgroundWorker1.Dispose()
                       End If
                       BackgroundWorker1.RunWorkerAsync(tbl(i))
     
                       While (FlagBGK = False)
                       End While
     
                Next
    Avant d'envoyer, je regarde si le BGW est occupé, si oui, je demande l'arrêt de celui-ci.


    Dans mon DoWork :

    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
     Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
     
           Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
     
            WriteRS232(CStr(e.Argument))
     
            FlagBGK = True
     
            While (True)
                If worker.CancellationPending Then
                    e.Cancel = True
                    Exit Sub
                End If
            End While
    End Sub



    Lorsque je demande l'arrêt du BGW, je passe bien dans les instructions "e.Cancel" et "Exit Sub".
    Pourtant, à la sortie, si je regarde si mon BGW.IsBusy, j'ai un true.
    Quelqu'un sait pourquoi?

    Merci d'avance de votre aide!

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    ton code est plutot fouilli et pas assez complet je ne comprends pas trop ...

    sinon un while true ce n'est pas une bonne idée, il faut mettre au minimum un system.threading.thread.sleep(1) dedans, sinon ca prend tout le processeur possible pour ne rien faire ...
    (idem pour le while flag=false)

    disposer le bgw juste après le cancelasync ca me parait étrange aussi
    de plus dispose sert à libérer la mémoire = on ne s'en sert plus, or 2 lignes plus loin tu l'utilises ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Femme Profil pro
    Apprentie
    Inscrit en
    Avril 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprentie

    Informations forums :
    Inscription : Avril 2016
    Messages : 18
    Par défaut
    Bonjour Pol et merci de ta réponse.

    J'ai changé mon code en incluant le sleep, merci pour cette amélioration.

    Il ne s'agit que d'une partie du code, je comprends qu'on peut s'y perdre. Mais pour resitué le contexte : j'envoie de grosses données sur le port RS232 grâce à WriteRS232, qui prend en argument un string. Des données tellement grosse que je perds la main sur la fenêtre lors de l'envoie. La solution serait de mettre cette fonction dans un backgroundworker.
    Je n'utilise donc ce backgroundworker que lorsque je dois envoyer des données. (Pourquoi pas utiliser un autre thread tout simple? Parce que j'en ai déjà un et que je m'embrouille!)

    C'est pour cela que je lance le backGroundWorker et que je l'arrête dès que l'envoie des données est terminé : je n'en ai plus besoin jusqu'au prochain envoi. Cela me permet aussi de changer l'argument, et donc, de texte à envoyer.

    Dans le premier bout de code : dans une boucle for, je mets le flag à zero, je teste si le BGW est actif. Si oui, je "l'arrête", sinon, je le lance avec comme argument mon tableau de string.
    Dans le deuxième code : j'envoie les données, je change le flag pour dire que le travail est fait et que l'on peut maintenant arrêter le thread, (Dans un Run..Completed, je ne passez pas tout le temps dedans.) et j'attends d'être arrêté.


    J'ai mis un dispose parce que.... j'ai testé beaucoup de choses pour arrêter le BGW, dont ça! Mais oui, je peux l'enlever, ça ne change pas grand chose.


    J'espère avoir été plus clair.

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    le bgw s'arrête tout seul, à la sortie de la sub DoWork

    il y a un mécanisme d'annulation, mais c'est bien pour annuler quelque chose
    ce mécanisme est vide, et il faut implémenter soit même le code (tester cancellationpending comme tu sembles l'avoir fait)

    par contre tester ce booléen n'est possible que quand on a un traitement en plusieurs étapes (ou encore mieux sur une boucle)
    or ici c'est l'envoi de données qui prend du temps, soit une seule ligne de code, donc ici ce mécanisme ne peut pas fonctionner :
    avant tu n'as rien donc il ne s'est pas écoulé de temps
    et après le send toute l'action est terminée, il n'y a donc rien à annuler
    si vraiment tu veux pouvoir annuler en plein milieu de l'envoi, il va falloir découper ta trame en morceaux de genre 1ko (ou moins) et faire une boucle qui envoi le morceau puis teste le booléen (plutot que tout envoyer en une seule ligne de code)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre averti
    Femme Profil pro
    Apprentie
    Inscrit en
    Avril 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprentie

    Informations forums :
    Inscription : Avril 2016
    Messages : 18
    Par défaut
    (En fait le WriteRS232 ne se fait pas en une ligne de code, je transforme des données hexa en binaire,..., pour ensuite les envoyer, dans la même fonction ^^)


    Mais du coup, d'après ce que tu me dis, je me rends compte que je n'aurais en fait pas besoin d'arrêter le thread, si j'ai bien compris.
    J'ai donc essayé un bout de code très très simple :

    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
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            For i = 5 To 6
                While (BackgroundWorker1.IsBusy)
                    System.Threading.Thread.Sleep(1)
                End While
                BackgroundWorker1.RunWorkerAsync(i)
            Next
     
            MsgBox("Envoi terminé")
        End Sub
     
     
        Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
     
            MsgBox("J'ai terminé")
     
        End Sub
     
     
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
     
            Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
            Dim result As Integer
     
            result = e.Argument + 1
            MsgBox(result)
            FlagBGK = True
    End Sub

    j'ai également testé sans boucle for.

    Si j'ai bien compris ce que tu m'as dit, après la ligne "FlagBGK = True", je sors du DoWork, je dois aller dans le RunWorkerCompleted : mon backGroundWorker est terminé.
    Or ce n'est pas le cas : lors du deuxième passage sur la boucle, je reste sur busy, je ne rentre pas dans le RunWorkerCompleted, sauf si j'enlève le sleep, et dans ce cas, je n'y rentre qu'une seulement fois.
    Pourrais-tu/Pourriez-vous m'expliquer?

    Merci de ton aide.

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    Citation Envoyé par KelaireM Voir le message
    (En fait le WriteRS232 ne se fait pas en une ligne de code, je transforme des données hexa en binaire,..., pour ensuite les envoyer, dans la même fonction ^^)
    oui enfin transformer de l'hexa en binaire à moins de coder avec la pieds ca prends quelques micro secondes

    Citation Envoyé par KelaireM Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            For i = 5 To 6
                While (BackgroundWorker1.IsBusy)
                    System.Threading.Thread.Sleep(1)
                End While
                BackgroundWorker1.RunWorkerAsync(i)
            Next
     
            MsgBox("Envoi terminé")
        End Sub
    l'envoi n'est pas terminé au moment du messagebox, le bgw est sur un autre thread
    donc exécuté en même temps que le code qui execute le button1.click, qui sort dans la foulée

    après le for i = 5 to 6, s'il n'y a pas d'autre code que ca c'est étrange aussi
    si le bgw prend du temps, cette boucle qui attend qu'il ne soit plus busy va bloquer l'interface



    Citation Envoyé par KelaireM Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
     
            Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
            Dim result As Integer
     
            result = e.Argument + 1
            MsgBox(result)
            FlagBGK = True
    End Sub
    pas de msgbox autorisé ici je pense, comme tout ce qui est interface (auquel cas ca plante, ca sort du bgw en notant que ca c'est fini avec une exception, et le flag ne serait pas mis à true)

    bref, encore beaucoup de flou
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

Discussions similaires

  1. Pas d'événement OnClose quand on arrête W2K
    Par Altau dans le forum C++Builder
    Réponses: 9
    Dernier message: 26/01/2009, 18h36
  2. BackgroundWorker et arrêt
    Par daner06 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 08/06/2007, 14h49
  3. Arrêt de l'exécution d'une requête MySQL dans DELPHI.
    Par joelmarc dans le forum Bases de données
    Réponses: 9
    Dernier message: 11/10/2004, 16h11
  4. [MFC] Attendre l'arrêt d'un processus !!
    Par Djoz dans le forum MFC
    Réponses: 6
    Dernier message: 29/07/2003, 12h03
  5. Détecter l'arrêt du système ?
    Par Jéremy A dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 24/03/2003, 19h06

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