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 :

Interrompre le travail des backgroundworker lors de la fermeture du formulaire [Débutant]


Sujet :

VB.NET

  1. #1
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut Interrompre le travail des backgroundworker lors de la fermeture du formulaire
    Bonjour à tous,
    J'ai un bug dans ma ligne cbCol.datasource = ListCars lorsque je tente de fermer le formulaire avant la fin du chargement des données effectuées par des Backgroundworker.
    En effet, mon code fonctionne très bien sauf dans le cas ou je tente de fermer le formulaire, à ce moment là cbCol devient égale à Nothing puisque les contrôles ont été détruit.

    J'ai dans l'idée qu'il faudrait soit pouvoir arrêter le backgroundworker dans le Form.closing ou alors tester une variable dans l’évent du bgw pour savoir quand l'UI est inaccessible et ainsi pouvoir faire un exit sub mais je ne sais pas si une telle variable existe ni comment faire exactement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Private Sub bgwCars_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwCars.RunWorkerCompleted
        Dim cbCol As DataGridViewComboBoxColumn = CType(DataGridViewCars.Columns("Dépendance"), DataGridViewComboBoxColumn)
        ListCars.Sort()
        cbCol.DataSource = ListCars         
     
     End Sub
    Merci beaucoup d'avance pour votre aide.

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    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 154
    Points : 25 072
    Points
    25 072
    Par défaut
    IsDisposed permet de savoir si un control a été détruit
    https://msdn.microsoft.com/fr-fr/lib...vs.110%29.aspx

    si tu fermes tes fenetres avec .close au lieu de .dispose pas sur que ca aille
    après tu peux setter un booléen dans le formclosing


    pour arreter le bgw, ca dépend de ce qu'il fait, s'i c'est un boucle tu peux tester un booléen dans la boucle pour arreter au plus tot
    si c'est une seule instruction non annulable tu ne peux que faire interrupt (enfin ca se fait sur un thread, sur un bgw je ne sais pas si on peut)
    le bgw encapsule un peu le traitement d'une annulation (WorkerSupportsCancellation, CancellationPending, CancelAsync()) mais c'est à toi de la coder, la méthode ne fait que setter le booléen à true ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci beaucoup Pol63.

    Je ferme ma fenêtre en faisant un clique sur la croix en haut à droite, j'imagine que ça revient à faire un .close.
    J'ai setté un boolean dans Form.closing et je m'en sert pour sortir de l'event RunWorkerCompleted. Après une trentaine de tentatives je n'ai plus l'erreur bien que je reste prudent car ça dépend du moment ou je clique....

    Je passe en résolu néanmoins, je pense que ça fonctionne....

    Merci pour tout....

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    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 154
    Points : 25 072
    Points
    25 072
    Par défaut
    pour tester les trucs qu'un jedi devrait tester, tu peux rajouter un peu de rien pendant un certains temps, genre au début du bgw.dowork :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    system.threading.thread.sleep(2000)
    ce qui te laisse 2 seconde pour cliquer avant qu'il commence à exécuter le code qui suit
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Déjà fondamentalement ton exemple m'a l'air boiteux.

    Normalement, dans les règles de l'art, le background worker doit fournir ces valeurs de retour (et d'entrée) à l'aide de la propriété Result (respectivement Argument) de l'évenement DoWork. Ensuite dans l'événement RunWorkerCompleted, on récupère ce résultat puis on l'utilise (pour modifier un contrôle ou peupler un objet de donnée liée aux contrôle).

    La je vois pas exactement ce que tu fais mais tu m'a l'air de passer par la variable ListCars pour gérer le passage du résultats et que cette variable est par la suite utilisée comme source de données. C'est le meilleur moyen de se prendre des bonnes veilles Exceptions de thread dans la tronche.

    Après concernant ton problème précis, le plus juste (ça n'engage que moi) et de prendre le problème à l'envers. C'est à dire de vérifier dans l'événement Form Closing que le background worker n'est pas en train de bosser (Propriété IsBusy) et d'annuler la fermeture du formulaire si c'est le cas. Ainsi tu t'assure que le worker a non seulement terminé son travail, mais aussi que le formulaire a traité le retour (ce qui peut avoir son importance).

    Ca n'empêche pas d'aller plus loin en ajoutant une gestion d'annulation dans le backgroundworker et d'essayer d'annuler le travail avant d'annuler la fermeture du formulaire.

  6. #6
    Expert confirmé
    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
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    @sinople : Je plussois.

  7. #7
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci beaucoup pour vos lumières...Pour ce qui est du code boiteux...j'ai déjà fait bien pire mais je m'en suis toujours sortie...
    Ça c’était pour la blague mais vos conseils sont toujours très précieux pour moi.
    @Sinople, tu as vus juste. Je me sert d'une variable Public ListCars pour gérer le passage de résultats. Mais pas seulement, le BackGroundWorker remplie plusieurs listes. Comment faire dans ce cas pour passer plusieurs Objets de type List ou Dictionary dans l'argument Result ?

    C'est une question générale et récurrente en fait, je me pose toujours la question de savoir si je dois passer des arguments à une procédure ou déclarer une variable public....Si la variable n'a qu'une utilité ponctuel alors j'utilise un argument et si la variable a une utilité dans presque tous le programme alors j'utilise une variable public....
    Ça c'est pour les données d'entrées, en sortie c'est plus compliqué car souvent je renvois plusieurs résultat et recourir à un objet personnalisé juste pour retourner un résultat je trouve ça lourd...Si vous avez un avis la dessus, je suis preneur.

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    C'est simple. Tu crées un objet qui contient une propriété pour chaque liste. Ca peut très bien être un tableau de collection.

    Après il peut aussi être intéressant d'avoir plusieurs background worker afin d'avoir une partie du résultat qui arrive plus vite. Et aussi pour éviter que le code de traitement du retour d'un background worker soit trop lourd ce qui gélera aussi l'interface (vu qu'à la base c'est ce qu'on essaye d'éviter). Mais bon on s'éloigne du sujet.

    Après oui, les solutions "bracaillons" ont est tous passé par là... (et on est bien content quand on a compris comme "bien faire" pour qu'au final ça marche.)

  9. #9
    Expert confirmé
    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
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par BasicZX81 Voir le message
    Comment faire dans ce cas pour passer plusieurs Objets de type List ou Dictionary dans l'argument Result ?
    e.Result est de type Object donc tu peux créer un tableau avec des types différents comme par exemple :


    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
     
    Private Sub Bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Bgw.DoWork
        '......
        '.........
        '.............
        ' C'est juste un exemple : 
        Dim Result as object = Nothing
        If ListCars.Count = 0 Then
            Result = new Object() {"Error", ListCars}
        Else
            Result = new Object() {"Success", ListCars}
        End If
        e.result = Result 
    End Sub
     
      Private Sub Bgw_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Bgw.RunWorkerCompleted
            If Not e.Result Is Nothing Then
                Select Case e.Result(0)
                    Case "Success"
     
                    Case "Error"
     
                End Select
            Else
     
            End If
    End Sub
    Il peut tout aussi bien être judicieux d'utiliser une classe ou une structure pour l'utiliser dans ton code.

    A+

  10. #10
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Ah oui, les tableaux d'objets. Je l'avait oublié celui-là...
    C'est parce que je suis obnubilé par l'usage systématique des variables typées....

    Merci beaucoup.

  11. #11
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    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 154
    Points : 25 072
    Points
    25 072
    Par défaut
    tu peux travailler en typé aussi
    tu fais un classe avec une propriété par liste que tu veux retourner, typées donc
    dans le dowork tu instancies cette classe, tu remplies les propriétés, et c'est cette instance de classe que tu mets dans le result
    tu cast dans l'event et après c'est typé ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 29/02/2012, 09h15
  2. Réponses: 3
    Dernier message: 15/06/2010, 16h29
  3. Réponses: 2
    Dernier message: 09/01/2008, 08h50
  4. Réponses: 2
    Dernier message: 26/11/2007, 12h59
  5. Réponses: 1
    Dernier message: 20/08/2007, 22h57

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