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 :

Thread et ProgressBar


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Par défaut Thread et ProgressBar
    Bonjour à tous,
    J'ai besoin de générer une tache de fond qui exécutera certain travaux de gestion et ou d'affichage sans monopoliser le thread principal.
    j'ai cherché sur le net et j'ai trouvé qlq chose de simple, de compréhensible rapidement, mais ça marche pas
    http://support.microsoft.com/kb/315577/fr
    Ci-dessous le code :
    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
    Imports System.Threading
     
    Public Class Form1
     
        Private trd As Thread
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            trd = New Thread(AddressOf ThreadTask)
            trd.IsBackground = True
            trd.Start()
        End Sub
     
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show("This is the main thread")
        End Sub
     
        Private Sub ThreadTask()
            Dim stp As Integer
            Dim newval As Integer
            Dim rnd As New Random()
     
            Do
                stp = ProgressBar1.Step * rnd.Next(-1, 2)
                newval = ProgressBar1.Value + stp
                If newval > ProgressBar1.Maximum Then
                    newval = ProgressBar1.Maximum
                ElseIf newval < ProgressBar1.Minimum Then
                    newval = ProgressBar1.Minimum
                End If
     
                ProgressBar1.Value = newval
     
                Thread.Sleep(100)
            Loop
        End Sub
     
    End Class
    le Debog se lance et crash au bout d'une seconde avec cette erreur :
    Opération inter-threads non valide : le contrôle 'ProgressBar1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé.
    je comprend bien le message d'erreur mais n'ai aucune idée pour faire en sorte que cela fonctionne, et vous ?
    Patrick

  2. #2
    Membre Expert Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Par défaut
    Tout est dit ici : Comment : faire des appels thread-safe aux contrôles Windows Forms

    Avant de te lancer dans l'inter-thread, doc-toi sur les Invoke et les Delegate

  3. #3
    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 patrickvier,

    Je ne vois pas trop l'intérêt de mettre en pratique cet exemple car la progression est aléatoire et ne se termine jamais du fait que la variable d'incrémentation est issu d'un random !
    Lorsque tu rencontres ce genre d'erreur (même si tu dis savoir la comprendre sans pour autant pouvoir la résoudre o_O), c'est que tu essayes de mettre à jour un composant situé sur l'interface (UI) de ton programme, or tu ne délègues pas cette tache.

    Il faut créer un délégué et l'appeler en lieu et place de ce qui te permet actuellement de mettre à jour ta progressbar comme cela :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    Imports System.Threading
     
    Public Class Form1
     
        Private trd As Thread
     
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            If trd.IsAlive Then
                trd.Abort()
            End If
        End Sub
     
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            trd = New Thread(AddressOf ThreadTask)
            trd.IsBackground = True
            trd.Start()
        End Sub
     
        Private Delegate Sub UpdateProgressBarDelegate(ByVal progress%)
        Private Sub UpdateProgressBarMethod(ByVal progress%)
            If Not progress > 100 Then
                Me.ProgressBar1.Value = progress
            End If
        End Sub
     
        Private Sub ThreadTask()
            Dim stp As Integer
            Dim newval As Integer
            Dim rnd As New Random()
     
            Do
                stp = ProgressBar1.Step * rnd.Next(-1, 2)
                newval = ProgressBar1.Value + stp
                If newval > ProgressBar1.Maximum Then
                    newval = ProgressBar1.Maximum
                ElseIf newval < ProgressBar1.Minimum Then
                    newval = ProgressBar1.Minimum
                End If
     
                If Me.InvokeRequired Then
                    Me.Invoke(New UpdateProgressBarDelegate(AddressOf UpdateProgressBarMethod), newval)
                End If
                'ProgressBar1.Value = newval
     
                Thread.Sleep(100)
            Loop
        End Sub
     
    End Class
    Tu remarqueras qu'en quittant l'application il faut impérativement libérer les ressources monopolisées par ton thread (trd) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        If trd.IsAlive Then
                trd.Abort()
            End If

    Si les thread te rebutent un peu, tu peux également utiliser le composant "backgroundWorker" qui est très complet et fait très bien ce job de gestion de thread.


    A+ et bon codage.

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Par défaut
    Merci à tous les 2 pour votre aide.
    Il est vrai que les délégués sont encore obscures pour moi
    En fait, dans le Thread, je traite des données toutes les minutes et ce temps là est géré par un timer...
    Je ne suis pas si c'est la bonne méthode.
    Merci encore.
    Patrick.

  5. #5
    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 patrickvier Voir le message
    Merci à tous les 2 pour votre aide.
    Il est vrai que les délégués sont encore obscures pour moi
    En fait, dans le Thread, je traite des données toutes les minutes et ce temps là est géré par un timer...
    Je ne suis pas si c'est la bonne méthode.
    Merci encore.
    Patrick.
    Si tu traites des données toutes les minutes alors je pense que l'utilisation de Timer Callbacks devrait faire l'affaire sans trop se prendre la tête :
    http://tutorials.csharp-online.net/C...imer_Callbacks

    Cet exemple est bien illustré mais il faut que tu prévois de disposer l'objet Timer qui a été instancié préalablement !

    PS : attention quand je parle de timer je ne parle pas du composant Timer issu de l'espace de noms "System.Windows.Forms" mais de la classe issue de l'espace de noms "System.threading" ! Ce n'est pas la même chose !

    A+

Discussions similaires

  1. [PERL/TK] Thread et ProgressBar
    Par remix55 dans le forum Interfaces Graphiques
    Réponses: 19
    Dernier message: 31/08/2010, 18h40
  2. Problème Thread et progressbar
    Par AnsuzPeorth dans le forum GTK+ avec Python
    Réponses: 2
    Dernier message: 19/03/2010, 12h56
  3. thread et progressBar sous Visual C++
    Par goingoin dans le forum VC++ .NET
    Réponses: 5
    Dernier message: 19/03/2009, 16h59
  4. Thread et ProgressBar
    Par Jidewe dans le forum VB.NET
    Réponses: 3
    Dernier message: 27/05/2008, 10h04
  5. Background Thread et ProgressBar
    Par bgcode dans le forum VB.NET
    Réponses: 17
    Dernier message: 05/07/2007, 13h30

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