none
Usercontrol et BackgrounWorker? RRS feed

  • Question

  • Bonjour a tous

     

    j'ai fais un petit usercontrol avec un backgroundworker, mais quand j'ajoute l'usercontrol et que je l'exécute la form reste figé un moment.

    donc d'après ce que je comprend c'est que l'usercontrol hérite de form1 de certaine propriété.

    Par exemple, qui ce produit avec un move sur un controle dans l'usercontrol, cela ce produit !

      Private Sub bg_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bg.ProgressChanged<br/>
        For i As Integer = 0 To 500<br/>
          Threading.Thread.Sleep(50)<br/>
          Panel1.Location = New Point(Panel1.Location.X, Panel1.Location.Y + i)<br/>
        Next<br/>
      End Sub
    

    Quand je fait ce petit bout de code (en dehors de l'usercontrol) cela fonctionne plutot bien dans le backgroundworker, la form ne ce fige pas

    La question est comment faire a partir d'un usercontrol des traitement lourd sans figé la form (l'application) en passant par un backgroundworker ou pas ?

     

    En vous remerciant d'avance

     

     

     

     

     


    Cordialement, Troxsa
    mardi 30 novembre 2010 15:01
    Auteur de réponse

Réponses

  • Donc avec une ProgressBar sur un formulaire et :

      ProgressBar1.Style = ProgressBarStyle.Marquee
      ProgressBar1.Maximum = 10
      ProgressBar1.MarqueeAnimationSpeed = 250
      ProgressBar1.Step = 1
    

    Cela me donne une animation de la progressbar. La feuille reste réactive (si j'ajoute par exemple des "checkbox" je peux les cocher/décocher sans latence perceptible).

    Si on veut faire une animation perso, je pense qu'il serait peut-être préférable de déconnecter cette animation du "ProgressChanged" (je pense à un Timer) en particulier si le pourcentage n'est pas utilisé.

    On ne pause que 50 ms mais on va le faire 500 fois ce qui fait 25 s pour exécuter une seule fois ProgressChanged ?!

    Que fait exactement ce UserControl ? Il embarque à la fois un traitement d'arriere plan avec l'interface utilisateur qui va avec ?

    Avec un panel avec fond rouge et un timer cela me donne par exemple :

     Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
      Timer1.Interval = 250
      Timer1.Start()
     End Sub
    
     Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
      Panel1.Width += 5
      If Panel1.Width > Me.Width Then
       Panel1.Width = 0
      End If
     End Sub
    
    Je n'ai pas eu le temps d'ajouter par dessus un BackgroundWorker mais je ne pense pas que cela ait un effet contraire...

    Je confirme j'ai ajouté un backgroundworker et le panel continue à s'élargir pendant qu'il s'exécute et totu reste réactif. Je pense que le problème original est que le ProgressChanged est trop long à s'exécuter... 

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    mardi 30 novembre 2010 17:35
    Modérateur

Toutes les réponses

  • Bonjour,

    ProgressChanged est exécuté sur le thread de l'interface utilisateur. Il faudrait donc que ce code soit le plus rapide possible et l'appeler le moins souvent possible (par exemple une erreur classique est de l'appeler depuis le travail d'arrière-plan même si le pourcentage d'avancement ne change pas ce qui va exécuter du code sur le UI thread pour rien).

    Quel est le but de ce code ? Il n'utilise même pas le pourcentage. Si le but est de faire une animation pendant l'exécution du travail d'arrière-plan la progress bar dispose d'un mode permettant de faire cela...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    mardi 30 novembre 2010 15:30
    Modérateur
  • Patrice Scribe

     

    Oui c'est dans le but de faire une animation d'un control.

    vous dites que la progressbar dispose d'un mode permettant de faire cela ?
    Hum ... c'est a dire ? pourriez vous me donner un exemple ou me mettre sur la piste. Faut t'il que l'usercontrol herite du control progress bar ?

     

    A bientot


    Cordialement, Troxsa
    mardi 30 novembre 2010 15:37
    Auteur de réponse
  • Donc avec une ProgressBar sur un formulaire et :

      ProgressBar1.Style = ProgressBarStyle.Marquee
      ProgressBar1.Maximum = 10
      ProgressBar1.MarqueeAnimationSpeed = 250
      ProgressBar1.Step = 1
    

    Cela me donne une animation de la progressbar. La feuille reste réactive (si j'ajoute par exemple des "checkbox" je peux les cocher/décocher sans latence perceptible).

    Si on veut faire une animation perso, je pense qu'il serait peut-être préférable de déconnecter cette animation du "ProgressChanged" (je pense à un Timer) en particulier si le pourcentage n'est pas utilisé.

    On ne pause que 50 ms mais on va le faire 500 fois ce qui fait 25 s pour exécuter une seule fois ProgressChanged ?!

    Que fait exactement ce UserControl ? Il embarque à la fois un traitement d'arriere plan avec l'interface utilisateur qui va avec ?

    Avec un panel avec fond rouge et un timer cela me donne par exemple :

     Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
      Timer1.Interval = 250
      Timer1.Start()
     End Sub
    
     Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
      Panel1.Width += 5
      If Panel1.Width > Me.Width Then
       Panel1.Width = 0
      End If
     End Sub
    
    Je n'ai pas eu le temps d'ajouter par dessus un BackgroundWorker mais je ne pense pas que cela ait un effet contraire...

    Je confirme j'ai ajouté un backgroundworker et le panel continue à s'élargir pendant qu'il s'exécute et totu reste réactif. Je pense que le problème original est que le ProgressChanged est trop long à s'exécuter... 

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    mardi 30 novembre 2010 17:35
    Modérateur
  • Effectivement, comme PAtrice la signifié, un timer permet de faire l'Animation. Mais encore là il faut pas trop en mettre dans le Tick du timer et ne pas mettre l'interval trop petit. Normalement, en 250ms l'oeil ne devrait pas s'apercevoir et cela devrait donner une impression de continu.
    Microsoft MVP C# || gabrielmongeon.com || LinkedIn
    mardi 30 novembre 2010 18:26
    Modérateur
  • Merci pour vos conseils.

     

    Le but de cette usercontrol est de faire un peux comme si on tournais une page a l'aide d'un bouton a droite et gauche.

    je sais pas trop si vous voyez ce que je veux dire ...

    dans le code que j'ai donné c'est, effectivement, juste la base de ce qui a été fait pour commencé l'usercontrol, en voyant que ça fonctionnais pas, j'ai fais quelle recherche. En voyant qu'il y a pas grand chose sur ce probleme j'ai pas continué mon code et j'suis venu ici pour une aide :)

     

    Je vais essayé de faire ce que vous m'avez conseillés :)

     

    A bientot


    Cordialement, Troxsa
    mardi 30 novembre 2010 18:50
    Auteur de réponse
  • Avec le timer ça fonctionne tres bien, merci

    Voila ce que j’essaie de faire...

    Imports System.ComponentModel
    
    Public Class UserControl1
      Private WithEvents timer1 As New Timer
      Private oPos As Integer = 0
    
      Sub New()
        ' Cet appel est requis par le concepteur.
        InitializeComponent()
    
        ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
        timer1.Enabled = False
        timer1.Interval = 10
    
      End Sub
    
      Private Enum oDirection
        Droite = 0
        Gauche = 1
        Haut = 2
        Bas = 3
      End Enum
    
      Private Sub boutoncliquer(ByVal odirect As oDirection)
        Panel1.Size = New Size(Panel1.Size.Width, Panel1.Size.Height)
        Panel1.Dock = DockStyle.None
        timer1.Enabled = True
      End Sub
    
      Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer1.Tick
        Panel1.Location = New Point(Panel1.Location.X + oPos, Panel1.Location.Y)
        oPos += 1
        If Panel1.Location.X = Me.Location.X Then
          timer1.Enabled = False
        End If
      End Sub
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        boutoncliquer(oDirection.Droite)
      End Sub
    
      Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        boutoncliquer(oDirection.Gauche)
      End Sub
    
      Private newPanel As New Panel
      <Browsable(True), Category("Panel"), Description("Ajoute une interface Panel page")> _
      Public Property xPanel As Control
        Get
          Return newPanel
        End Get
        Set(ByVal value As Control)
          newPanel = value
        End Set
      End Property
    
    
    End Class
    
    

    Mon userControl a deux boutons (a doite, et l'autre a gauche), ses deux boutons sont tout les deux docker (un a droite et l'autre a gauche), le panel lui est au centre docker aussi, je souhaiterais pouvoir ajouté plusieurs panels dans une collection (propriété) et de pouvoir choisir un de ses panels pour y déposer des contrôles (une sorte de wizard)

    je sais pas trop encore comment tout faire car je me lance dans quelle que chose que je connais encore tres mal ;)

     

    Merci pour autre aide

     

     


    Cordialement, Troxsa
    mardi 30 novembre 2010 19:43
    Auteur de réponse