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 :

BackgroundWorker, Progress Bar et utilisation de Thread multiples ?


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut BackgroundWorker, Progress Bar et utilisation de Thread multiples ?
    Bonjour,

    Toujours dans la suite de mon projet je souhaite faire en sorte que pour chaque ordinateur connecté sur le réseau je puisse "télecharger" un fichier après l'exécution d'un script sur la machine distante.

    Procédure :

    1) L'utilisateur clique sur un bouton (plus tard se traitement sera sûrement automatisé)
    2) le programme va donc exécuter un script sur une machine distante et récupérer le fichier généré par le script. Cette action est executée autant de fois qu'il y a de machines sur le réseau.

    Pour simuler ce traitement j'utilise un backgroundworker.

    Dans la gestion du bouton j'appele le background worker :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Sub bouton( .... ) 
     
    ' je récupère la liste des machines distantes dite "online" dans une liste 
    ' puis je créer une progress bar
     
    Me.pgb = new progressBar ' nom du form contenant la progress bar
    Me.pgb.Visible = True
     
    If Not Me.bgworker.IsBusy Then
             Me.bgworker.RunWorkerAsync(list)
    End If
     
    end sub
    Simulation de la tâche : execution des scripts distants et récupération des fichiers générés :

    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
    private sub bgworker_DoWork() 
     
    ' liste contenant les IPs
    Dim machines As List(Of String) = e.Argument
     
    For i As Integer = 0 To (machines.Count - 1)
     
                bgworker.ReportProgress(i)
                Dim machine As New machine(machines(i))
                Thread.Sleep(1)
     
    Next
     
    ' e.result = liste de fichiers générés sur chaque machine distante
     
    If bgworker.IsBusy Then
        If bgworker.WorkerSupportsCancellation Then
            bgworker.CancelAsync()
        End If
    End If
    end sub
    Traitement de l'actualisation de la barre de progression :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub bgworker_ProgressChanged( ...)
            Me.pgb.progress_bar.Value = e.ProgressPercentage + 1
            Me.pgb.label_count.Text = Me.pgb.progress_bar.Value
    End Sub
    Traitement lorsque le backgroundworker est terminé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Sub bgworker_RunWorkerCompleted(....)
     
    Me.pgb.progress_bar.Value = Me.pgb.progress_bar.Maximum
    ' mise à jour du tableau avec les données des machines distantes
    '  dgv = directcast(e.result,collection_de_fichier) 
     
    End Sub
    J'ai plusieurs questions :

    Premièrement en qui concerne la gestion de l'execution du script distant et de la récupération des fichiers généres. Est-ce que la méthode que j'utilise est correcte ? (je céer un objet "machine" qui va se charger pour chaque machine de l'exécution du script et de copier le fichier de la machine distante sur la machine locale) .

    Est-ce que de tout gérer dans un seul Thread est correct ou c'est plus performant de gérer un thread par machine distante ?

    Pour la barre de progression (valeure max=100), en simulant le traitement j'obtiens un résulat assez satisfaisant. C'est à dire que si j'ai 5 machines, ma barre progresse de 5 puis arrivé à 5 continue jusqu'à atteindre la fin.

    Cependant j'ai un comportement que je ne comprend pas.

    1) je lance mon application
    2) clique sur le bouton pour simuler l'execution du script distant :

    -----> La barre de progression s'affiche mais se bloque pendant +/- 15 secondes avant de commencer à défiler, puis s'incrémente de 1 jsuqu'au nombre total de machines.

    Je ne comprend pas les raisons pour lesquelles la barre de progression se met en attente pendant une "longue" durée de +/- 15 secondes avant de défiler.

    3) pour tester à nouveau je reclique sur le bouton pour simuler à nouveau l'exécution du script. Et là, je n'est pas de temps d'attente. La barre de progression démarre bien et se termine correctement.

    Merci pour votre aide !

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    Citation Envoyé par iOops Voir le message
    Premièrement en qui concerne la gestion de l'execution du script distant et de la récupération des fichiers généres. Est-ce que la méthode que j'utilise est correcte ? (je céer un objet "machine" qui va se charger pour chaque machine de l'exécution du script et de copier le fichier de la machine distante sur la machine locale) .
    ca semble pas mal

    Citation Envoyé par iOops Voir le message
    Est-ce que de tout gérer dans un seul Thread est correct ou c'est plus performant de gérer un thread par machine distante ?
    ca dépend du traitement
    en général si on a 10 choses à faire et qu'on a 4 cores sur la machine, il vaut mieux les faire 4 par 4 jusqu'à faire les 10 (avec threadpool par exemple)
    dans certains cas il vaudrait mieux faire les 10 à la fois
    et dans d'autres cas il vaudrait mieux en faire entre 4 et 10 à la fois
    ca dépend du traitement, si c'est un traitement ou tu passes du temps à attendre il vaut mieux faire les 10 en même temps
    donc si tu envoies une demande à la machine et que tu attends qu'elle ait fini il faudrait un thread par machine

    Citation Envoyé par iOops Voir le message
    -----> La barre de progression s'affiche mais se bloque pendant +/- 15 secondes avant de commencer à défiler, puis s'incrémente de 1 jsuqu'au nombre total de machines.
    l'interce freeze pendant ce temps ?

    Citation Envoyé par iOops Voir le message
    je reclique sur le bouton pour simuler à nouveau l'exécution du script. Et là, je n'est pas de temps d'attente. La barre de progression démarre bien et se termine correctement.
    ca peut aussi être quelque chose que tu n'as pas réinitialisé qui fait que le traitement est en fait différent
    à savoir aussi, un exe .net est compilé à chaque exécution au fur et à mesure de son exécution, une 2ème passage quelques part est toujours plus rapide car déjà compilé (par contre ca ne fait pas 15s de différences, c'est en ms en général ^^)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If bgworker.IsBusy Then
        If bgworker.WorkerSupportsCancellation Then
            bgworker.CancelAsync()
        End If
    End If
    et ca j'ai pas compris
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Execution des scripts distants :

    L'ordinateur ne dois pas être un foudre de guerre et un multi coeur je pense pas qu'il en ait un. De toute facon je pense faire machine par machine comme ca je peux controler si je récupére bien le fichier pour chaque pc. J'ecrirai le résultat dans un fichier log. Cela permettra de controler si tout c'est correctement dérouler.

    Progress bar :

    L'interface ne freeze pas. Elle semble en attente. Je parle bien de secondes et non de ms. J'ai chronométré avec mon horloge windows

    J'ai fait un test avec le debugger de Visual Studio 2008 et aussi avec la version .exe générée. J'obtiens le même résultat,

    Lorsque je lance pas à pas avec le debugger, je constate bien que je rentre dans ma boucle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    For i As Integer = 0 To (machines.Count - 1)
     
                bgworker.ReportProgress(i)
                Dim machine As New machine(machines(i))
                Thread.Sleep(1)
     
    Next
    Puis comemnce à incrémenter la barre de progression :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub bgworker_ProgressChanged( ...)
            Me.pgb.progress_bar.Value = e.ProgressPercentage + 1
            Me.pgb.label_count.Text = Me.pgb.progress_bar.Value
    End Sub
    Ma valeure est à 2 pour l'instant, or je peux constater que si je fait un pas à pas je peux voir ma valeur s'incrémenter, mon label n'est pas mis à jour (il reste à un, et la barre de progression n'avance pas).

    Lors de la deuxième exécution, je peux constater une incrémentaiton correcte de la valeur.

    Cette partie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If bgworker.IsBusy Then
        If bgworker.WorkerSupportsCancellation Then
            bgworker.CancelAsync()
        End If
    End If
    Ne sert à rien je l'ai suprimée.

  4. #4
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut Début de solution ?
    J'ai peut être un début de réponse à mon probème.
    J'ai créé un nouveau backgroundworker qui appele la même barre de progression que j'utilise dans mon exemple de départ. Dans ce backgroundworker je fais un traitement plus simple. Une boucle comptant jusqu'a 10 par exemple. Dès que je clique sur un bouton, la barre de progression démarre sans se laisser désirer, défile tout en métant à jour mon label affichant la valeur retournée par backgroudworker.ReportProgress().

    Je pense que ma barre de progression dans mon exemple de départ met beaucoup de temps à se lancer car j'exécute un ping.async et que l'UI est en attente de la fin du ping que j'effectue...

    En supprimant l'appel de la fonction ping du bouton, je m'appercoit que la barre n'a pas besoin de 15 secondes pour commencer à défiler, et dans se cas il semble que je me retrouve dans le même cas qu'avec mon nouveau backgroundworker créé spécialement pour mon test.

    Qu'en pensez-vous ?

  5. #5
    Membre Expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Par défaut
    Tout traitement (dans ton cas le ping.async) dans le thread principal (donc celui de l'UI) qui prend un certain temps ralenti l'exécution de celui-ci et donc freeze l'UI. Maintenant dans certain cas ce n'est qu'une initialisation donc ca ne vaux pas la peine de créer un thread pour cela.

    Tu peux tout simplement changer le curseur en sablier le temps de l'attente la fin de ton poing.

    Maintenant dans le framework 4.5 je pense une notion de fonction asynchrone a été ajoutée mais je n'ai pas encore regardé donc je ne sais pas si cette notion pourrait t'aider mais c'est une piste.
    Articles sur les technologies .NET

    Une réponse vous a aidé ? utilisez le bouton

    Votre problème est résolu ? utilisez le bouton

  6. #6
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Citation Envoyé par infosam76 Voir le message
    Tout traitement (dans ton cas le ping.async) dans le thread principal (donc celui de l'UI) qui prend un certain temps ralenti l'exécution de celui-ci et donc freeze l'UI. Maintenant dans certain cas ce n'est qu'une initialisation donc ca ne vaux pas la peine de créer un thread pour cela.

    Tu peux tout simplement changer le curseur en sablier le temps de l'attente la fin de ton poing.

    Maintenant dans le framework 4.5 je pense une notion de fonction asynchrone a été ajoutée mais je n'ai pas encore regardé donc je ne sais pas si cette notion pourrait t'aider mais c'est une piste.
    Est-ce que si j'externalise le traitement du ping dans une classe a part cela evitera que mon application soit "bloquee"?

    Je peux tres bien imaginer une classe reseau avec en constructeur une liste d'ip ou une ip/hostname simple et l'appeler dans un thread a part depuis le thread principal. Cette classe me permettrai de connaitre l'etat des machines sur le reseau (connectee/non connectee) toutes les secondes ou avec un delais determine par l utilisateur.

    La barre de progression est importante pour moi car je souhaite aussi montrer a l'utilisateur l'etat d'avancement de l'importation des fichiers distant pour la mise a jour de tu tableau.

Discussions similaires

  1. [Débutant] Progress bar dans un nouveau thread ?
    Par yayou49 dans le forum VB.NET
    Réponses: 6
    Dernier message: 30/03/2015, 11h45
  2. utilisation d'une progress bar avec un timer
    Par devock dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 22/12/2006, 12h57
  3. Progress bar & upload multiple $_FILES
    Par fabien14 dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 04/12/2006, 18h34
  4. Utiliser la progress bar d'excel (celle dans la status bar)
    Par mustang-ffw02 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 13/04/2006, 17h59
  5. [MFC] Utilisation d'une progress bar
    Par nmarf dans le forum MFC
    Réponses: 2
    Dernier message: 12/09/2005, 10h42

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