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

Développement Windows Discussion :

Events et threads


Sujet :

Développement Windows

  1. #1
    Membre averti
    Inscrit en
    Août 2007
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 18
    Par défaut Events et threads
    Bonsoir tout le monde,
    ça fait 3 jours que je galère et j'ai pas trouvé la solution, bien, mon problème est le suivant :
    j'ai développé une classe qui extrait des données, et pour connaitre la progression de l'extraction j'ai créé un event dans cette classe et je le raise dans la boucle d'extraction des données, voici un petit morceau de code pour éclaircir ce que je viens de dire :

    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
     
    Public Class MaClass
     
    Public Delegate Sub ProgressEventHandler(ByVal Percentage As Integer)
     
    Public Event Progress As ProgressEventHandler
     
    Public Sub Extracting()
     
    'maCollection est une collection qui contient des données, j'ai pas copié tout
    'le code parce que c'est trop long.
    for i as integer=0 to maCollection.Count-1
     
    'un traitement pour l'extraction
    RaiseEvent Progress(Math.Round((i / maCollection.Count) * 100))
     
    Next
     
    End Sub
     
    End Class
    quand j'instancie ma classe dans une form, tout marche à merveille, sauf que, vu que le traitement de l'extraction est un lourd, donc il y a le freeze de la form, j'ai pensé au BackgroundWorker, ça marche , mais sans que je peux faire le handle de l'évenement "Progress".

    et voici le code que j'ai utilisé dans la form :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Public Class Form1
      Private WithEvents x As maClasse
     
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    X.Extracting()
    End Sub
     
    Private Sub X_Progress(ByVal Percentage As Integer) Handles X.Progress
            ProgressBar1.Value = Percentage
    End Sub
     
    End Class
    j'ai vraiment besoin d'aide pour ça, Visual Basic .Net ou C# il n'y a pas de différence, mais il faut que je trouve une solution pour ça et merci d'avance.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Si tu exécutes ton traitement dans un BackgroundWorker, il s'exécute dans un thread différent de celui de l'interface graphique, donc le handler de l'évènement aussi. Or, seul le thread de l'interface graphique peut manipuler les contrôles... Donc je suppose que tu obtiens une exception quand tu essaies de faire ProgressBar1.Value = Percentage

    Pour forcer ce code à s'exécuter sur le thread de l'interface, il faut utiliser la méthode Invoke :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Sub X_Progress(ByVal Percentage As Integer) Handles X.Progress
            Invoke(New Action(AddressOf SetProgress), Percentage)
    End Sub
     
    Private Sub SetProgress(ByVal Percentage As Integer)
            ProgressBar1.Value = Percentage
    End Sub
    Sinon, la solution la plus simple est d'utiliser la méthode ReportProgress du BackgroundWorker. Celle-ci déclenche un évènement ProgressChanged qui se produit sur le thread de l'interface graphique, et non sur celui du BackgroundWorker, donc tu n'as rien de particulier à faire pour le gérer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ...
    ' dans ton traitement :
    backgroundWorker1.ReportProgress(Math.Round((i / maCollection.Count) * 100))
    ...
     
     
    Private Sub backgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles backgroundWorker1.ProgressChanged
        ProgressBar1.Value = e.ProgressPercentage
    End Sub

Discussions similaires

  1. Récupération d'event avec thread
    Par koyot3 dans le forum VB.NET
    Réponses: 1
    Dernier message: 17/09/2010, 08h25
  2. Création events pour thread
    Par syphon22 dans le forum Langage
    Réponses: 3
    Dernier message: 19/01/2010, 08h50
  3. Swing Event Dispatching Thread
    Par YeFFreY dans le forum EDT/SwingWorker
    Réponses: 14
    Dernier message: 23/06/2008, 10h53
  4. [C# 1.1] - Event & Thread
    Par Erakis dans le forum Windows Forms
    Réponses: 11
    Dernier message: 11/07/2006, 00h20
  5. [C#]Thread, event/delegate et Form
    Par doccpu dans le forum Windows Forms
    Réponses: 28
    Dernier message: 01/08/2005, 18h35

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