Appeler une fonction avec des paramètres dans un BackGroundWorker

Résolu
Utilisateur anonyme - 25 nov. 2012 à 13:33
 Utilisateur anonyme - 21 janv. 2013 à 22:45
Bonjour,
je voudrais appeler une fonction de scan de fichiers récursive dans un BackGroundWorker mais cette fonction nécessite des paramètres ( en l’occurrence les extensions ) et je ne sais pas du tout comment faire parce que je ne peux pas créer la fonction dans ma fonction BackGroundWorker.
Voici le code de ma fonction :
Private Sub ChercherFichiers(dossier As IO.DirectoryInfo, Extensions() As String)
        Try
            'pour chaque extension...
            For Each ext As String In Extensions
                '...on fait une liste des fichiers concernés...
                Dim f() As IO.FileInfo = dossier.GetFiles("*." & ext)
                '...et on ajoute les fichiers à la listbox
                For Each Fichier As IO.FileInfo In f
                    ListboxFichiersTrouvés.Items.Add(Fichier.FullName)
                Next
            Next
            'recherche des sous-dossiers...
            For Each d As IO.DirectoryInfo In dossier.GetDirectories
                'et recherche récursive des fichiers
                ChercherFichiers(d, Extensions)
            Next
        Catch ex As Exception
        End Try
    End Sub


Voici l'autre fonction où les paramètres sont définis ( mais ce n'est pas celle ci que je pense mettre dans mon BackGroundWorker ) :

Private Sub RécupérerFichiersImages()
        'recherche dans tous les disques
        For Each drive As IO.DriveInfo In IO.DriveInfo.GetDrives
            If drive.IsReady Then
                'ici je recherche les jpg, gif ...
                ChercherFichiers(New IO.DirectoryInfo(drive.RootDirectory.ToString), {"JPG", "GIF", "BMP", "DXF", "EPS", "PCX", "PICT", "PS", "TIFF", "WPG", "PNG", "MNG"})
            End If
        Next
    End Sub


Merci d'avance pour votre aide.

8 réponses

Utilisateur anonyme
25 nov. 2012 à 15:50
Bonjour,

Utilise plutôt des threads traditionnels plutôt qu'un Composant BackGroudWorker (très limité pour les paramétrages).

Voici un exemple simple et commenté :
Option Strict On
Public Class Form1

    'délégué pour éviter les opérations inter-thread (actualisation liste)
    Private Delegate Sub DelegateThreadSafe(ByVal Fichier As IO.FileInfo)

    'classe devant être passée au thread par sa méthode Start
    Public Class clsObjet
        Public Dossier As IO.DirectoryInfo
        Public Extensions As String()
        Sub New(ByVal pDossier As IO.DirectoryInfo, ByVal pExt As String())
            Dossier = pDossier
            Extensions = pExt
        End Sub
    End Class

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'déclaration d'un thread devant exécuter la sub ChercheFichiers
        Dim P As New Threading.Thread(AddressOf ChercheFichiers)
        'Start attend un paramètre objet (on va donc lui fournir une instance de la classe clsObjet)
        P.Start(New clsObjet(New IO.DirectoryInfo("c:"), New String() {"gif", "jpg", "bmp"}))
    End Sub

    Private Sub ChercheFichiers(ByVal Parametre As Object)
        Try
            'ici je dois caster mon paramètre dans le bon type
            Dim MonObjet As clsObjet = DirectCast(Parametre, clsObjet)
            'pour chaque extension...
            For Each ext As String In MonObjet.Extensions
                '...on fait une liste des fichiers concernés...
                Dim f() As IO.FileInfo = MonObjet.Dossier.GetFiles("*." & ext)
                '...et on ajoute les fichiers à la listbox
                For Each Fichier As IO.FileInfo In f
                    Me.Invoke(New DelegateThreadSafe(AddressOf RempliListe), Fichier)
                Next
            Next
            'recherche des sous-dossiers...
            For Each d As IO.DirectoryInfo In MonObjet.Dossier.GetDirectories
                'et recherche récursive des fichiers
                ChercheFichiers(New clsObjet(d, MonObjet.Extensions))
            Next
        Catch ex As Exception
        End Try
    End Sub


    Private Sub RempliListe(ByVal Fichier As IO.FileInfo)
        ListBoxFichiersTrouvés.Items.Add(Fichier.FullName)
        ListBoxFichiersTrouvés.SelectedIndex = ListBoxFichiersTrouvés.Items.Count - 1
        ListBoxFichiersTrouvés.Refresh()
    End Sub

End Class
3
Utilisateur anonyme
26 nov. 2012 à 22:29
Il suffit d'introduire une boucle énumérant tous les lecteurs disponibles.
A noter qu'un nouveau thread sera lancé pour chaque lecteur.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'énumération de tous les lecteurs
    For Each Drive As IO.DriveInfo In IO.DriveInfo.GetDrives
        'si le lecteur est prêt...
        If Drive.IsReady Then
            '...déclaration d'un thread devant exécuter la sub ChercheFichiers
            Dim P As New Threading.Thread(AddressOf ChercheFichiers)
            'Start attend un paramètre objet (on va donc lui fournir une instance de la classe clsObjet)
            P.Start(New clsObjet(New IO.DirectoryInfo(Drive.RootDirectory.FullName), New String() {"gif", "jpg", "bmp"}))
        End If
    Next
End Sub
3
Utilisateur anonyme
21 janv. 2013 à 22:40
Salut banana32,
et oui, 2 mois après je travail toujours sur mon programme juste pour te dire que j'ai trouvé pourquoi les fichiers étaient listés deux fois, c'est tout bête ... Dans mon évènement clique sur le bouton, BouttonListerFichiers.Click est présent deux fois !!! Donc c'est comme-ci je cliquais deux fois !

Private Sub BouttonListerFichiers_Click(sender As Object, e As EventArgs) Handles BouttonListerFichiers.Click, BouttonListerFichiers.Click
3
Utilisateur anonyme
26 nov. 2012 à 19:31
Salut banana32,
encore une fois une réponse net précise et efficace et qui fonctionne, le résultat est bluffant !
J'ai regardé le code et j'ai plus ou moins compris. ( Je trouve ça hyper compliqué pour mon niveau ) mais il y a une ligne que j'ai du mal à comprendre :
P.Start(New clsObjet(New IO.DirectoryInfo("c:"), New String() {"gif", "jpg", "bmp"}))

le ("C:") c'est juste un paramètre en fait parce que lui il en a besoin mais il n'en tiendra pas compte ? Parce que si j'ai un C: & un D: il scannera les deux.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
27 nov. 2012 à 22:35
Ok très bien, j'ai une dernière question après je clos le sujet, j'ai chercher pendant une heure dans tout le code mais je ne comprends pas pourquoi les fichiers toujours listés avec fluidité et classe sont listés deux fois chacun ?
0
Utilisateur anonyme
27 nov. 2012 à 23:09
J'ai oublié le code :
Public Class Form1
    'délégué pour éviter les opérations inter-thread (actualisation liste)
    Private Delegate Sub DelegateThreadSafe(ByVal Fichier As IO.FileInfo)
    'classe devant être passée au thread par sa méthode Start
    Public Class clsObjet
        Public Dossier As IO.DirectoryInfo
        Public Extensions As String()
        Sub New(ByVal pDossier As IO.DirectoryInfo, ByVal pExt As String())
            Dossier = pDossier
            Extensions = pExt
        End Sub
    End Class
    Private Sub ChercherFichiers(ByVal Parametre As Object)
        Try
            'ici je dois caster mon paramètre dans le bon type
            Dim MonObjet As clsObjet = DirectCast(Parametre, clsObjet)
            'pour chaque extension...
            For Each ext As String In MonObjet.Extensions
                '...on fait une liste des fichiers concernés...
                Dim f() As IO.FileInfo = MonObjet.Dossier.GetFiles("*." & ext)
                '...et on ajoute les fichiers à la listbox
                For Each Fichier As IO.FileInfo In f
                    Me.Invoke(New DelegateThreadSafe(AddressOf RemplirListe), Fichier)
                Next
            Next
            'recherche des sous-dossiers...
            For Each d As IO.DirectoryInfo In MonObjet.Dossier.GetDirectories
                'et recherche récursive des fichiers
                ChercherFichiers(New clsObjet(d, MonObjet.Extensions))
            Next
        Catch ex As Exception
        End Try
    End Sub
    Private Sub RemplirListe(ByVal Fichier As IO.FileInfo)
        ListboxFichiersTrouvés.Items.Add(Fichier.FullName)
        ListboxFichiersTrouvés.SelectedIndex = ListboxFichiersTrouvés.Items.Count - 1
        ListboxFichiersTrouvés.Refresh()
        LabelNombreFichiersTrouvés.Text = "Nombre De Fichiers Trouvés : " & ListboxFichiersTrouvés.Items.Count
    End Sub
    Private Sub RécupérerFichiersImages()
        'énumération de tous les lecteurs
        For Each Drive As IO.DriveInfo In IO.DriveInfo.GetDrives
            'si le lecteur est prêt...
            If Drive.IsReady Then
                Dim P As New Threading.Thread(AddressOf ChercherFichiers)
                'Start attend un paramètre objet (on va donc lui fournir une instance de la classe clsObjet)
                P.Start(New clsObjet(New IO.DirectoryInfo(Drive.RootDirectory.FullName), New String() {"JPG", "GIF", "BMP", "DXF", "EPS", "PCX", "PICT", "PS", "TIFF", "WPG", "PNG", "MNG"}))
            End If
        Next
    End Sub
Private Sub BouttonListerFichiers_Click(sender As Object, e As EventArgs) Handles BouttonListerFichiers.Click, BouttonListerFichiers.Click
        If CheckBoxImages.Checked = True Then
            Call RécupérerFichiersImages()
        End If
        If CheckBoxVidéos.Checked = True Then
            Call RécupérerFichiersVidéos()
        End If
        If CheckBoxDocuments.Checked = True Then
            Call RécupérerFichiersDocuments()
        End If
        If CheckBoxAudio.Checked = True Then
            Call RécupérerFichiersAudio()
        End If

    End Sub
0
Utilisateur anonyme
28 nov. 2012 à 23:08
Je ne vois pas. Peut-être que le problème se passe ailleurs dans ton code.

Note qui n'a rien à voir avec le sujet:
Tu as écris la ligne de code suivante :
If CheckBoxImages.Checked = True Then
Or CheckBoxImages.Checked est un booléen ce qui veut dire que tu as écris :
Si vrai = vrai alors

Tu peux donc simplifier par :
Si vrai alors

Et ton code donne alors :
If CheckBoxImages.Checked Then

Pour l'inverse, on rajoute le mot clé Not :
If Not CheckBoxImages.Checked Then


Note 2:
L'instruction Call est obsolète et peut être supprimée.
0
Utilisateur anonyme
21 janv. 2013 à 22:45
C'est bon à savoir, j'aurais cru que l'IDE de VS l'aurait signalé. Je ne savais même pas que c'était possible.

Bonne prog ;)
0
Rejoignez-nous