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

Windows Forms Discussion :

Backgroundworker et ouverture childform [Fait]


Sujet :

Windows Forms

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 285
    Points : 99
    Points
    99
    Par défaut ouverture form : Backgroundworker ou thread ?
    Bonjour,

    J’appelle une ChildForm via le menustrip d’une MDIForm. Cette ChildForm met pas mal de temps à s’ouvrir du fait de nombreux paramètres.

    J’aimerai donc faire apparaître une autre form (Form1) sur laquelle il n’y aurait qu’une progressbar pendant que ma ChildForm se charge, puis à 100% de la progressbar, fermeture de Form1 et affichage de la ChildForm.

    Le code actuellement contenu dans le menustrip (sans le Backgroundworker) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       Dim ChildForm As New ChildForm 
          ChildForm.MdiParent = Me
          ChildForm.Show()

    J’ai suivi le contenu des liens ci-dessous mais je ne parviens pas à mon but :
    http://glarde.developpez.com/dotnet/bgworker/vb/
    http://www.developpez.net/forums/d61...e-form-parent/
    http://www.developpez.net/forums/d63...-temps-enorme/
    http://plasserre.developpez.com/v8-5.htm

    Merci par avance de votre aide et bonne année 2009
    Merci de votre aide

  2. #2
    Membre régulier
    Inscrit en
    Juillet 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 285
    Points : 99
    Points
    99
    Par défaut
    Bonjour,

    En relisant attentivement le tuto de glarde (« il est totalement interdit de manipuler les contrôles de l'interface utilisateur. » qui me renvoie bien l’erreur indiquée dans le tuto), j’ai modifié l’appel de ma ChildForm. Je ne le fais plus depuis le menustrip de la MDIForm mais j’ouvre d’abord une autre form (Form2) pour ensuite appeler la ChildForm.

    Cependant, je ne parviens pas à bien cerner l’utilisation du Backgroundworker pour mon cas. Où le placer, sur Form1 (celle où il y a la progressbar), Form2 (celle de l’appel de l’ouverture de ChildForm) ?

    Cette discussion semble être une bonne piste mais je ne vois pas comment l’adapter par manque de connaissances.
    Merci de votre aide

  3. #3
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Je ne sais vraiment quelle est la meilleure façon de faire...
    Une possibilité est de lancer un BackgroundWorker qui affiche la form d'attente, et quand la ChildForm est prête à être affichée, tu arrêtes le BackgroundWorker :
    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
     
    ' initialiser et démarrer le BGW
    Dim bgw As New BackgroundWorker
    bgw.WorkerSupportsCancellation = True
    AddHandler bgw.DoWork, AddressOf bgw_DoWork
    bgw.RunWorkerAsync()
     
    ' faire ce qui prend du temps (initialiser ChildForm dans ton cas)
    ...
     
    ' quand c'est terminé, arrêter le BGW
    bgw.CancelWorkerAsync()
     
     
    ...
     
    ' Le traitement du BGW :
    Private Sub bgw_DoWork(sender As Object, e As DoWorkEventArgs)
        Dim f As New Form2()
        f.Show()
        While(Not bgw.CancellationPending)
            Application.DoEvents()
            Thread.Sleep(100)
        End While
        f.Close()
    End Sub
    C'est pas très académique... normalement c'est le traitement long qu'on fait dans le backgroundworker, mais je fais comme ça à cause du problème des appels cross-threads. Le seul intérêt d'utiliser le BackgroundWorker ici est que la form d'attente tourne dans son propre thread et n'est donc pas bloquée

  4. #4
    Membre régulier
    Inscrit en
    Juillet 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 285
    Points : 99
    Points
    99
    Par défaut
    Re,

    D'abord merci Tomlev pour la réponse.

    Par rapport à
    quand la ChildForm est prête à être affichée
    et au code pour ouvrir ChildForm (dans le 1er post), je ne vois absolument pas à quoi peut correspondre le "quand"?
    Merci de votre aide

  5. #5
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par kgb1917 Voir le message
    Par rapport à et au code pour ouvrir ChildForm (dans le 1er post), je ne vois absolument pas à quoi peut correspondre le "quand"?
    Quand tu as fini d'exécuter les instructions du bloc "' faire ce qui prend du temps (initialiser ChildForm dans ton cas)". Donc rien de particulier à faire, met juste le CancelWorkerAsync à la suite

  6. #6
    Membre régulier
    Inscrit en
    Juillet 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 285
    Points : 99
    Points
    99
    Par défaut
    Bonsoir,

    Je reviens sur ce sujet parce que même si le code de Tomlev fonctionne, il ne correspond pas complètement à ce que je souhaite faire.

    Concrètement :
    - Sur Form1, clic sur bouton1 qui lance la procédure d’ouverture de Form2 (celle qui prend du temps).
    - Pendant cette procédure, ouverture d’une form d’attente (Form3).
    - Sur Form3, un bouton qui permet d’interrompre la procédure d’ouverture de Form2 et ferme Form3 en même temps (Form1 reste ouverte).

    C’est le dernier point qui me fait reposter et pour y parvenir, j’ai l’impression que le backgroundworker n’est pas une bonne option (je peux me tromper). J’ai essayé de lancer un nouveau thread depuis Form1 pour la procédure d’ouverture de Form2 et me donner la possibilité de le supprimer via le bouton de Form3, sans succès.

    J’ai regardé attentivement les tutos d’Aspic sur les threads et les délégués et backgroundworker ainsi qu’un peu partout sur le forum, sans résultat satisfaisant.

    Bref, si qqun pouvait éclairer ma lanterne...
    Merci de votre aide

  7. #7
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par kgb1917 Voir le message
    - Sur Form3, un bouton qui permet d’interrompre la procédure d’ouverture de Form2 et ferme Form3 en même temps (Form1 reste ouverte).
    Ca, tu vas avoir du mal...
    Pour faire ça, il faudrait pouvoir interrompre l'appel au constructeur de Form2. Hors le seul moyen de faire ça serait d'interrompre le thread qui fait cet appel. Si c'est le thread principal, en faisant ça tu "tues" l'application. Il faudrait donc le faire dans un autre thread, mais les fenêtres doivent être créées dans le thread principal. Donc tu es coincé...

    Il faudrait peut-être revoir la façon dont tu initialises Form2... qu'est-ce qui prend du temps exactement ? l'initialisation des contrôles, ou un autre traitement (chargement de données par exemple) ? Dans le second cas il faudrait le faire non pas dans le constructeur, mais dans une autre méthode qui serait exécutée sur un autre thread, et qui n'accèderait pas à l'interface.

  8. #8
    Membre régulier
    Inscrit en
    Juillet 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 285
    Points : 99
    Points
    99
    Par défaut
    Salut Tomlev,

    Pour la Form2, je suis bien dans le 2ème cas (chargement de données). Seulement, très gros problème, je fais des choix dans Form1 qui sont pris en compte comme paramètres pour l'ouverture de Form2, et là, je ne vois pas comment faire sans passer par le thread de Form1.
    Merci de votre aide

  9. #9
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    il suffit de transmette les choix à Form2 (en paramètre de la méthode de traitement par exemple)

  10. #10
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 156
    Points : 25 075
    Points
    25 075
    Par défaut
    sur form1 qui demande ouverture de form2 avec form3 pour attendre :
    dim f as new form3 (param1,param2...)


    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
    public class form3
     
      private _thLoad as system.threading.thread
      private _form2 as form2
      private _param1 as  ..
      private _param2 as  ..
     
      public sub new (param1,param2...)
        me.show
        _form2 = new form2 (me)
        _param1 = param1
        _param2 = param2
        _thLoad = new system.threading.thread(adressof initform2)
        _thLoad.start
      end sub
     
      public sub initform2
        form2.init(param1,param2...)
      end sub  
     
     
      private delegate sub DelegueSetProgressBarValue(v as integer)
     
      public sub SetProgressBarValue(v as integer)
        if me.invokerequired then  
          dim d as new DelegueSetProgressBarValue(adressof SetProgressBarValue)
          me.invoke(d,v)
        end if
     
        me.progressbar1.value = v
      end sub
     
      private sub bouton annuler_click handles boutonannuler.click
         _thLoad.interrupt  'version violente
      end sub
     
    end class
    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
     
    public class form2
     
      private _form3 as form3
     
      public sub new (f as form3)
        _form3 = f
      end sub
     
      public sub init(param1, param2 ...) ' chargement des données
        'traitement
        _form3.SetProgressBarValue(30)
        'traitement
        _form3.SetProgressBarValue(50)
        'traitement
        _form3.SetProgressBarValue(80)
     
        'fin du traitement
        _form3.dispose
        _form3 = nothing
      end sub
     
    end class

    ca devrait ressembler à ca

    ici pour l'arret du thread, j'ai mis la version violente et pas forcément recommandé, ca dépend du traitement que tu fais
    sinon le mieux est d'avoir un booléen sur form2 qui sert à annuler le chargement, sur form3.boutonannuler.click, tu faisa
    _form2.annulerLoad = true
    _thLoad.join(1000) (ca demande d'attendre ici que le thread se termine, si au bout de 1000 ms c'est pas fini ca passe à la ligne d'après
    _thLoad.abort (ou interrupt)
    et sur form2.init tu test le plus souvent possible ce booléen, et s'il vaut true, tu ferme 2 ou 3 objets et tu fais exit sub (qui arretera le thread)

    abort déclenche une exception qui peut donc parfois etre dans du code de microsoft, donc c'est pas top, et c'est une des rares exceptions à se propager à travers tous les catch et provoque en général l'arret de la sub et donc du thread
    interrupt arrete le thread sans se poser de questions sans passer à la ligne d'après dans le thread
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre régulier
    Inscrit en
    Juillet 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 285
    Points : 99
    Points
    99
    Par défaut
    Bonjour,

    Merci sperot51, je teste tout ça et reviens vous dire quoi.
    Merci de votre aide

Discussions similaires

  1. Réponses: 2
    Dernier message: 09/02/2009, 13h48
  2. Resau local => ouverture et fermeture
    Par Nutcase dans le forum Développement
    Réponses: 8
    Dernier message: 17/11/2002, 15h16
  3. [TForm] Ne pas autoriser l'ouverture d'un form
    Par sbeu dans le forum Composants VCL
    Réponses: 6
    Dernier message: 11/10/2002, 11h20
  4. Réponses: 2
    Dernier message: 22/07/2002, 12h13
  5. Réponses: 2
    Dernier message: 04/06/2002, 10h34

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