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 :

Listing de dossiers avec BackgroundWorker


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2007
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 18
    Par défaut Listing de dossiers avec BackgroundWorker
    Bonjour,

    Je sollicite votre aide pour l'utilisation de BackgroundWorker, pour lequel j'ai du mal à saisir le fonctionnement.

    Voici mon souci:

    Je souhaiterais lister les dossiers d'un répertoire et afficher le contenu dans une Listbox se trouvant dans ma Form.

    En dehors du BackgroundWorker, cela fonctionne sans problème.

    Mais dès que j'intègre le code à un BackgroundWorker (pour éviter de bloquer complèment la Form et pouvoir lancer d'autres tâches simultanément), il m'affiche le très connu message "Cross-Thread operation not valid...".

    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     
    Liste_Des_Dossiers_ListBox.Items.Clear()
    Liste_Des_Dossiers_ListBox.Refresh()
     
    Liste_Des_Dossiers_BackgroundWorker.RunWorkerAsync()
     
    End Sub

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Liste_Des_Dossiers_BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Liste_Des_Dossiers_BackgroundWorker.DoWork
     
    Dim Dossier_Principal As String  = "c:\temp"
    Dim Liste_Des_Dossiers As New IO.DirectoryInfo(Dossier_Principal)
     
    For Each Dossier As IO.DirectoryInfo In Liste_Des_Dossiers.GetDirectories
     
    Liste_Des_Dossiers_ListBox.Items.Add(Dossier.ToString)
    Liste_Des_Dossiers_ListBox.Refresh()
     
    Next
     
    End Sub

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Private Sub Liste_Des_Dossiers_BackgroundWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Liste_Des_Dossiers_BackgroundWorker.RunWorkerCompleted
     
    MessageBox.Show("Listing des dossiers effectué")
     
    End Sub
    Il y a bien de nombreux forums qui traite du BackgroundWorker de manière générale, mais je ne trouve rien sur le listing de dossier.

    Pourriez-vous svp m'aider?

    Un grand merci

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    les controles ne sont modifiables que depuis le thread principal, pas depuis un autre thread comme celui créé par un backgroundworker
    sinon ca donne le message d'erreur que tu as (cross thread)

    http://www.developpez.net/forums/d10...m/#post5757425
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre éprouvé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 81
    Par défaut
    Et juste pour optimiser un peu, il vaut mieux récupérer tous les dossiers dans une liste, et ensuite venir l'appliquer à la Combobox. Cela générera moins d'événement que ta méthode actuelle.

  4. #4
    Membre Expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Par défaut
    Exemple d'utilisation d'un BackGroundWorker avec une progressBar :
    http://dotnet.developpez.com/telecha...ckgroundWorker

    sinon Sokhz n'a pas tord, Créez une liste dans votre fonction "Liste_Des_Dossiers_BackgroundWorker_DoWork" et vous la renvoyer en fin de fonction par e.Result ce qui va donner plus ou moins :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Liste_Des_Dossiers_BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Liste_Des_Dossiers_BackgroundWorker.DoWork
     
    Dim Dossier_Principal As String  = "c:\temp"
    Dim Liste_Des_Dossiers As New IO.DirectoryInfo(Dossier_Principal)
     
    For Each Dossier As IO.DirectoryInfo In Liste_Des_Dossiers.GetDirectories
     
     ' Ajout à la liste (SortedList par exemple)
     
    Next
     
    e.Result = LaListe 
    End Sub
    Et pour l'affichage vous implémentez la fonction suivante pour l'événement
    "RunWorkerCompleted" (Implémentation en C# ici):

    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
     
    void work_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                // L'objet RunWorkerCompletedEventArgs peut renvoyer une propriété (Error) contenant une information en cas d'erreur
                if (e.Error != null)
                {
                }
                else
                {
                    // Ou un résultat via la propriété Result
                    Type de la liste Ma Liste = (Type de la liste)e.Result
     
                    // Ajout dans votre Liste_Des_Dossiers_ListBox
                }
            }
    Articles sur les technologies .NET

    Une réponse vous a aidé ? utilisez le bouton

    Votre problème est résolu ? utilisez le bouton

  5. #5
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Par défaut
    @Sokhz :

    Cela va de soi vu que l'on ne peut accéder au composant graphique dans un autre thread comme le disait Pol63
    Mais maintenant grace à toi, Maximeus sait comment pallier à son problème

    1. Créer une liste en variable global
    2. Initialiser la liste avant le For Each dans le DoWork
    3. La remplire dans le DoWork
    4. La lier à la liste via la propriété Datasource dans RunWorkerCompleted


    @Maximeus :
    N'hésite pas à lire le lien de Pol63 qui explique bien le fonctionnement du Backgroundworker.

  6. #6
    Membre averti
    Inscrit en
    Septembre 2007
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 18
    Par défaut
    Merci pour votre aide. Cela fonctionne maintenant

    Voici mon code (ça pourra toujours dépanner qn en cas de besoin):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     
    Liste_Des_Dossiers_ListBox.Items.Clear()
    Liste_Des_Dossiers_ListBox.Refresh()
     
    Liste_Des_Dossiers_BackgroundWorker.RunWorkerAsync()
     
    End Sub
    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
     
    Liste_Des_Dossiers_BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Liste_Des_Dossiers_BackgroundWorker.DoWork
     
    Dim Dossier_Principal As String  = "c:\temp"
    Dim Liste_Des_Dossiers As New IO.DirectoryInfo(Dossier_Principal)
     
    Dim Table_Liste_Des_Dossiers As Datatable = New DataTable("Dossiers")
    Table_Liste_Des_Dossiers.Columns.Add("Dossiers", GetType(Object))
     
    For Each Dossier As IO.DirectoryInfo In Liste_Des_Dossiers.GetDirectories
     
    Table_Liste_Des_Dossiers.Rows.Add(Dossier.Name.ToString)
     
    Next
     
    e.result = Table_Liste_Des_Dossiers
     
    End Sub

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Private Sub Liste_Des_Dossiers_BackgroundWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Liste_Des_Dossiers_BackgroundWorker.RunWorkerCompleted
     
    Liste_Des_Dossiers_ListBox.DataSource = DirectCast(e.Result, DataTable)
    Liste_Des_Dossiers_ListBox.DisplayMember = "Dossiers"
    Liste_Des_Dossiers_ListBox.Refresh() 
     
    End Sub

    Salutations.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 81
    Par défaut
    Je peux chipoter? :p


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    For Each Dossier As IO.DirectoryInfo In Liste_Des_Dossiers.GetDirectories
     
    Table_Liste_Des_Dossiers.Rows.Add(Dossier.Name.ToString)
     
    Next
    Je préfère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Table_Liste_Des_Dossiers.Rows.AddRange(New IO.DirectoryInfo("c:\temp").GetDirectories.Select(Function(d) d.Name.ToString))
    C'est dommage de faire une boucle lorsque l'on a aucun traitement à faire dedans, si ce n'est récupérer les éléments sur lesquelles on itère. Pour faire les ajouts en masse, il y a généralement une méthode AddRange. Et si elle n'existe pas, un petit coup d'extension .. En l'occurence, AddRange n'existe pas sur les Rows, mais elle existe sur les colonnes

    De manière plus générale, tu utilises des variables dont tu pourrais te passer, même si elles sont locales, ça fait toujours ça d'économiser

    Après, c'est vrai que ça rend le code un peu moins lisible au premier coup d'oeil.

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

Discussions similaires

  1. [Batch] Liste des sous-dossiers avec leur nom et le nombre de fichier inclus
    Par sencha dans le forum Scripts/Batch
    Réponses: 5
    Dernier message: 05/02/2015, 11h27
  2. Réponses: 2
    Dernier message: 26/11/2009, 13h13
  3. OpenDialog avec une liste des dossiers favories
    Par J_apprenti dans le forum Delphi
    Réponses: 6
    Dernier message: 09/05/2007, 23h23
  4. Utilisation de la classe List de STL avec wxWidgets
    Par aoyou dans le forum wxWidgets
    Réponses: 7
    Dernier message: 10/03/2005, 18h41
  5. [std::list][find_if] problème avec mes foncteurs
    Par n!co dans le forum SL & STL
    Réponses: 12
    Dernier message: 04/02/2005, 12h56

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