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 :

utilisation du backgroundworker


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    developpeur
    Inscrit en
    Décembre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2011
    Messages : 141
    Par défaut utilisation du backgroundworker
    Bonjour à tous amis(e) développeurs

    Après de nombre recherche sur Google et pas mal de lecture http://glarde.developpez.com/dotnet/bgworker/vb/,
    je n'arrive toujours pas à me dépatouiller avec ce composant.

    Concrètement, j'ai un bouton ou se déroule bon nombre de calcul du type :

    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
    34
    35
    36
    37
    38
    39
    40
    41
     
     
               Form2.show
               Label1.text = "Etat : Etape 1/..."
     
    If CheckBox1.Checked = True And ComboBox2.Text = "45x40" Then
                Label94.Text = TextBox30.Text
                Label178.Text = "Prix en euros"
            End If
     
            If CheckBox1.Checked = True And ComboBox2.Text = "60x40" Then
                Label94.Text = TextBox29.Text
                Label178.Text = "Prix en euros"
            End If
     
            If CheckBox1.Checked = True And ComboBox2.Text = "65x40" Then
                Label94.Text = TextBox28.Text
                Label178.Text = "Prix en euros"
            End If
     
    etc.....
     
                Label1.text = "Etat : Etape 1/..."
     
     
            If CheckBox1.Checked = True And ComboBox2.Text = "75x40" Then
                Label94.Text = TextBox27.Text
                Label178.Text = "Prix en euros"
            End If
     
            If CheckBox1.Checked = True And ComboBox2.Text = "75x50" Then
                Label94.Text = TextBox26.Text
                Label178.Text = "Prix en euros"
            End If
     
            If CheckBox1.Checked = True And ComboBox2.Text = "75x60" Then
                Label94.Text = TextBox25.Text
                Label178.Text = "Prix en euros"
            End If
     
    etc....
    ou les label me donnent de résultat de prix....Bref

    Je souhaites "suivre" le déroulement de toutes ces actions par un label1 qui afficherai mon état pendant le calcul et pourquoi pas une progressbar1.
    J'ai donc créé un petite form2 ou j'y ai mi mon label et ma progressbar qui ce lance avant tous les calculs... mais l'application ce fige... et rien n'est visible.
    Est-ce qu'un backgroundworker serait adapté pour ce que je souhaites faire et comment faire ??

    J'ai as peu prés saisie ce genre de chose :

    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
    34
    35
    36
    37
    38
    39
    40
    41
    Private WithEvents BackgroundWorker1 As System.ComponentModel.BackgroundWorker
     
     
    BackgroundWorker1 = New System.ComponentModel.BackgroundWorker
     
    BackgroundWorker1.WorkerReportsProgress = True
    BackgroundWorker1.WorkerSupportsCancellation = True
     
    AddHandler BackgroundWorker1.DoWork, AddressOf BackgroundWorker1_DoWork
    AddHandler BackgroundWorker1.RunWorkerCompleted, AddressOf BackgroundWorker1_RunWorkerCompleted
    AddHandler BackgroundWorker1.ProgressChanged, AddressOf BackgroundWorker1_ProgressChanged
     
     
    Private Sub buttonstart_Click( _ByVal sender As System.Object, _ByVal e As System.EventArgs) _Handles btnStartCancel.Click
     
    RunWorkerAsync ??
     
     
    Private Sub "inconnu ?"_DoWork( _ByVal sender As System.Object, _ByVal e As System.ComponentModel.DoWorkEventArgs) _Handles "inconnu ?".DoWork
     
    -> Réalisation des traitement :
     
    If CheckBox1.Checked = True And ComboBox2.Text = "45x40" Then
                Label94.Text = TextBox30.Text
                Label178.Text = "Prix en euros"
            End If
     
    Suite des calcul etc....
     
    Private Sub "inconnu ?"_RunWorkerCompleted( _ByVal sender As Object, _ByVal e As RunWorkerCompletedEventArgs) _Handles "inconnue ?".RunWorkerCompleted
     
    	If Not (e.Error Is Nothing) Then
    		label1.Text = "Une erreur est survenue ! Détail : " + e.Error.Message
    	ElseIf e.Cancelled Then
    		label1.Text = "Opération annulée !"
    	Else
    		label1.Text = "Opération terminée ! Résultat : " + e.Result.ToString
    	End If
     
     
    End Sub

    "inconnu" étant ce que je ne sais pas faire comme je débute...

    Pourriez-vous m'aider à avancer si vous aviez des idée un peu plus concrête sur la chose ou bien même des exemples qui puissent m'aiguiller ??

    Merci beaucoup,

  2. #2
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    Bonsoir jeremyvb11,

    Avant toute chose il serait judicieux de ne pas mettre de code partiel d'autant plus que ce qui est intéressant d'identifier lorsqu'on utilise un composant BackgroundWorker :

    IMPORTANT : Importes le composant BackgroundWorker (depuis la boite à outils sur ton formulaire) en mode concepteur de vues !


    - la partie du code qui demande un traitement assez long = La partie Main Thread
    - la/les parties de code qui met à jour l'interface de ton programme (label, progressbar, contrôles....etc....) = La partie UI

    - Quand débute la tache :

    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
       Private Sub StartAsyncThread()
                'Permet de supporter la gestion de la progression
                Me.AsyncThread.WorkerReportsProgress = True
                'Permet de supporter l'annulation du traitement en cours
                Me.AsyncThread.WorkerSupportsCancellation = True
                'Si le composant n'est pas déjà occupé alors on lance la tache
                If Not AsyncThread.IsBusy Then
                    Me.AsyncThread.RunWorkerAsync()
                End If
            End Sub
     
       Private Sub AsyncThread_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles AsyncThread.DoWork
           'Tu mets à jour la partie UI en appelant le gestionnaire d'évènement "AsyncThread.ProgressChanged" et en passant 2 paramètres : 1 integer, 1 Object
           AsyncThread.ReportProgress(1,"Début du traitement")
           'Tu places dans le corps de cette procédure le code qui demande des traitements longs mais sans faire appel à des controles (label, listbox, combobox, textbox, ....)
           '....
           '.......
           'Tu mets à jour la partie UI 
           AsyncThread.ReportProgress(2,"Mise à jour du label")
           'Tu places du traitement long sans placer d'appel à des controles
           '....
           '.......
           AsyncThread.ReportProgress(3,"Mise à jour de la textbox")
           'Tu places du traitement long sans placer d'appel à des controles
           '....
           '.......
           AsyncThread.ReportProgress(4,"Finalisation du traitement")
     
            e.result = "Traitement achevé avec succès !"
            End Sub

    - Quand mettre à jour la partie UI :

    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 AsyncThread_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles AsyncThread.ProgressChanged
     
           Select Case e.ProgressPercentage
               Case 1,4
                   Me.text = e.userstate.tostring   
                   Exit Select
               Case 2
                   label1.text = e.userstate.tostring   
                   Exit Select
               Case 3
                   textbox1.text = e.userstate.tostring
                   Exit Select
           End Select
     
            End Sub
    - Quand la tache se termine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        Private Sub AsyncThread_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles AsyncThread.RunWorkerCompleted
            If e.Cancelled Then
                Msgbox("Opération annulée !")
            Else
                If Not e.Result Is Nothing Then
                    Msgbox(e.result.toString)
                End If
            End If
        End Sub
    Quand tu auras identifier tout ça alors tu seras prêt à le mettre en place.
    C'est vraiment une explication très très très basique ou je ne traite pas de tout...... mais j'espère que ça te permettra d'avoir une meilleure approche de ce composant.


    A+

  3. #3
    Membre très actif
    Homme Profil pro
    developpeur
    Inscrit en
    Décembre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2011
    Messages : 141
    Par défaut
    Bonsoir wallace1,

    Merci beaucoup pour ton aide, je vais cogiter là dessus et voir si j'ai compris ton raisonnement.

    Concernant les composant j'allais bien entendu les importer depuis la boite à outil

    Si j'ai bien compris ton exemple, les parties
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AsyncThread.ReportProgress(1,"Début du traitement")
    sont entre guillemets mes "étapes" ?

    Quand tu m'informes de "placer dans le corps de cette procédure le code qui demande des traitements longs mais sans faire appel à des controles (label, listbox, combobox, textbox, ....)" cela correspond à mes calculs je suppose, mais ces calculs sont des labels et textbox cela pose t'il probleme ?


    Merci beaucoup pour cet exemple dont je vais essayer de m'inspirer !

  4. #4
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par jeremyvb11 Voir le message
    Quand tu m'informes de "placer dans le corps de cette procédure le code qui demande des traitements longs mais sans faire appel à des controles (label, listbox, combobox, textbox, ....)" cela correspond à mes calculs je suppose, mais ces calculs sont des labels et textbox cela pose t'il probleme ?


    Merci beaucoup pour cet exemple dont je vais essayer de m'inspirer !
    mettre à jour des contrôles ou affecter des valeurs a des propriétés de controles ne corresponds en rien à du calcul !

    Ce n'est pas censé prendre un temps considérable pour les mettre à jour donc le backgroundworker (ou thread) est inutile à mon sens ! Ton code doit bloquer ailleurs.....


    Postes ton code qu'on puisse avoir matière à mieux t'orienter....

  5. #5
    Membre très actif
    Homme Profil pro
    developpeur
    Inscrit en
    Décembre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2011
    Messages : 141
    Par défaut
    Effectivement tu as raison ce n'est pas du calcul !

    Dans ton exemple le backgroundworker est nommé : AsyncThread
    et la progressbar est nommé : userstate ?

    Ne souhaitant pas avoir de "Cancel" sur le déroulement de l’événement, est-il possible de mettre simplement le démarrage sur mon button comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Private Sub button1_Click( _ByVal sender As System.Object, _ByVal e As System.EventArgs) _Handles button1.Click
     
    Me.AsyncThread.RunWorkerAsync()
     
    End sub
    Merci wallace1

  6. #6
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    Le BGW se nomme bien "AsyncThread" mais il n'y a pas de PgBar dans mon exemple ou du moins pas pour le moment !

    Lorsque tu lis du code il faut savoir identifier :

    1- Une méthode :
    - qui peut être une "Fonction"
    - qui peut être une "Procédure"

    En l'occurence cette procédure se nomme un gestionnaire d'évènement car il est suivi :
    - du mot clé "Handles"
    - de l'appel de l'évènement associé au composant BGW : "ProgressChanged"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       Private Sub AsyncThread_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles AsyncThread.ProgressChanged
     
       End Sub

    2- une signature de méthode :
    - qui peut être vide
    - qui peut contenir un ou plusieurs arguments

    En l’occurrence cette procédure contient 2 arguments :
    - sender de type Object (sender c'est le composant qui a fait l'objet de l'appel = le backgroundworker (AsyncThread))
    - e de type ProgressChangedEventArgs (e possède 2 propriétés : e.ProgressPercentage, e.Userstate)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       Private Sub AsyncThread_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles AsyncThread.ProgressChanged
     
       End Sub
    3- L'appel d'une méthode :

    Dans notre exemple l'appel de la méthode suivante dans le corps de notre gestionnaire d'évènement "AsyncThread.DoWork" permet de passer 2 arguments à notre autre gestionnaire d'évènement "AsyncThread.ProgressChanged" :
    - 1 (de type Integer)
    - "Début du traitement" (de type Object que l'on définit implicitement en type String)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     AsyncThread.ReportProgress(1,"Début du traitement")
    A l'issu de cet appel notre exécution de code se situe ici et nous retrouvons nos 2 arguments :
    - e.ProgressPercentage
    - e.Userstate

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       Private Sub AsyncThread_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles AsyncThread.ProgressChanged
     
       End Sub
    '#################################### Si tu décides de mettre une Progressbar #########################################

    Il faut savoir quelle est la valeur maximale qui corresponds à 100% (je ne vais pas t'apprendre à faire un produit en croix ^^)

    Tu as 4 étapes de progression, ce qui corresponds à ton 100% donc à chaque fois que tu appelles la méthode ".ReportProgress" il faut affecter la valeur d'incrémentation dans la progressbar qui devra se situer dans le gestionnaire d'évènement ".ProgressChanged" (Progressbar1.Value = e.ProgressPercentage * 100 / 4)

    Donc tu rajoutes une progressBar sur ton formulaire et tu places l'incrémentation de sa valeur dans le gestionnaire d'évènement suivant :

    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
     
      Private Sub AsyncThread_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles AsyncThread.ProgressChanged
           Select Case e.ProgressPercentage
               Case 1,4
                   Me.text = e.userstate.tostring   
                   Exit Select
               Case 2
                   label1.text = e.userstate.tostring   
                   Exit Select
               Case 3
                   textbox1.text = e.userstate.tostring
                   Exit Select
           End Select
           If Not e.ProgressPercentage * 100 / 4 > 100
               Progressbar1.Value = e.ProgressPercentage * 100 / 4
           End If
      End Sub
    '############################### Concernant la suppression de la méthode ".IsBusy" #########################################


    Imaginons que ta phase de calcul dure 2 minutes.

    L'user lance le backgroundWorker uniquement comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Private Sub button1_Click( _ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles button1.Click
     
        Me.AsyncThread.RunWorkerAsync()
     
    End sub
    Si l'user décide d'appuyer de nouveau sur le même bouton pour lancer une nouvelle tache avant que l'autre ne ce soit achevée (avant les 2 minutes) alors une erreur se produira du fait que tu n'utilises pas la méthode qui permet de savoir si une tache sur le BGW est déjà en cours comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Private Sub button1_Click( _ByVal sender As System.Object, _ByVal e As System.EventArgs) _Handles button1.Click
      'Si le composant n'est pas déjà occupé alors on lance la tache
                If Not AsyncThread.IsBusy Then
                    Me.AsyncThread.RunWorkerAsync()
                End If
    End sub
    A+

Discussions similaires

  1. Comment utiliser un backgroundworker (vb.net 2005) ?
    Par Aspic dans le forum Contribuez
    Réponses: 1
    Dernier message: 23/04/2013, 17h22
  2. Exemple d'utilisation du BackgroundWorker
    Par infosam76 dans le forum Contribuez
    Réponses: 0
    Dernier message: 06/12/2012, 22h15
  3. Utilisation du BackgroundWorker
    Par jlm22 dans le forum VB.NET
    Réponses: 12
    Dernier message: 15/04/2011, 16h13
  4. utilisation de BackgroundWorker
    Par infose dans le forum C#
    Réponses: 44
    Dernier message: 20/10/2010, 11h19

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