[.NET] Problème de BackGroundWorker

fdiedler2000 Messages postés 383 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 1 décembre 2008 - 21 mars 2007 à 15:56
fdiedler2000 Messages postés 383 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 1 décembre 2008 - 21 mars 2007 à 23:52
Bonjour j'ai découvert ce controle pour faire des transferts de fichier via des sockets mais j'ai un problème ! (sans blague ^^)


Donc, en fait le problème vient que je veux montrer la progression du
transfert à l'utilisateur avec ce controle et notamment sa procédure :
<!-- BEGIN TEMPLATE: bbcode_code -->

Code :

PrivateSub Bgw_ProgressChanged(ByVal sender AsObject, ByVal e As System.ComponentModel.ProgressChangedEventArgs)Handles Bgw.ProgressChanged
Pb.Value = e.ProgressPercentage
EndSub

<!-- END TEMPLATE: bbcode_code -->
Le problème c'est que j'appelle la méthode
Bgw.RunWorkerAsync(Arguments) dans un autre thread que le thread
principale (enfin je crois)
<!-- BEGIN TEMPLATE: bbcode_code -->

Code :

PrivateSub Client_Receive_String(ByVal Message AsString, ByVal Sock As Socket)Handles Client.Receive_String
Dim ret AsString() = Split(Message, ControlChars.VerticalTab)
 
SelectCase ret(0)
Case"GetOk"
Dim file AsNew IO.FileInfo(T_Chemin.Text)
 
Client.Send("Download" & ControlChars.VerticalTab & file.FullName & ControlChars.VerticalTab & file.Length)
 
Arguments.Sck = Sock
Arguments.Size = file.Length
 
Bgw.RunWorkerAsync(Arguments)
EndSelect
EndSub

<!-- END TEMPLATE: bbcode_code -->
Et donc l'event Bgw_ProgressChanged plante et un appel interthread est crée sur la progressbar...


Comment remédier au problème ? Merci d'avance

5 réponses

cs_Willi Messages postés 2375 Date d'inscription jeudi 12 juillet 2001 Statut Modérateur Dernière intervention 15 décembre 2018 22
21 mars 2007 à 19:29
Bonsoir,
Effectivement le backgroundworker travaille dans un thread à part. C'est pour cela que tu as une exception qui est levée dans ta méthode de rappel Bgw_ProgressChanged, en .Net2 tu ne peux pas modifier un objet qui appartient à autre thread (en l'occurence le thread principal pour ta ProgressBar).
Il faut donc passer par un délégué.

-----------------------------------------------------------------
-Déclare un délégué dans ta feuille:
Delegate Sub ProgressChangedEventHandler (value as Integer)

-Créé une méthode qui va affecter ta barre de progression:
Private Sub AfficheProgression (value as Integer)
   Pb.Value = value
End Sub

-Maintenant on va mettre en place notre délégué dans la méthode de rappel Bgw_ProgressChanged:
Private Sub Bgw_ProgressChanged(sender as Object,...........)

    Dim del as New ProgressChangedEventHandler (AddressOf AfficheProgression)

    Pb.Invoke(del, e.ProgressPercentage)

End Sub

-----------------------------------------------------------------

++
0
fdiedler2000 Messages postés 383 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 1 décembre 2008
21 mars 2007 à 19:38
Salut,

Bien sur on peut faire comme ca mais justement mon but etait de ne pas utiliser de délégués... sinon a quoi sert le BackGroundWorker !?

Je pensais que ce controle nous evitais de créer plein de delegués. Donc autant le supprimer si je suis comme meme obliger de créer de délégués. Le pire c'est que j'ai vu des applications presque comme moi qui faisait

PrivateSub Bgw_ProgressChanged(ByVal sender AsObject, ByVal e As System.ComponentModel.ProgressChangedEventArgs)Handles Bgw.ProgressChanged
Pb.Value = e.ProgressPercentage
End Sub

et ca marchais nickel ^^ alors pourquoi pas moi ? :(

Tien le lien : http://glarde.developpez.com/dotnet/bgworker/vb/
0
cs_Willi Messages postés 2375 Date d'inscription jeudi 12 juillet 2001 Statut Modérateur Dernière intervention 15 décembre 2018 22
21 mars 2007 à 19:55
Oui je sais cet événement est executer dans le même thread de le principal.
Comment as-tu créer ton objet backgroundWorker ? Dans l'IDE ou par le code ? Car si tu as ce message c'est que quelque chose n'a pas été respecté.
0
fdiedler2000 Messages postés 383 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 1 décembre 2008
21 mars 2007 à 20:07
je l'ai crée dans l'IDE et puis j'ai apeller la methode WorkerAsync(arguments) dans un autre thread qui est celui de la réception des messages de ma socket ! c'est peut etrepour ca que ca plante ! Peut etre que ce controle ne doit etre apellé que par le thread principale sinon ca plante non ?

De toute manière je viens de me rendre compte que le controle plante avec mon envoi de fichier :

Partie qui envoi :

Private Sub ClientDownloadingFromServer(ByVal Path As String, ByVal SizeTotal As Long, ByVal sock As Socket)
        Try
            Dim rdby As Long = 0
            Dim len As Integer = 0

            Dim buffed() As Byte = New Byte(4096) {}
            'Open the file requested for download
            Dim fin As FileStream = New FileStream(Path, FileMode.Open, FileAccess.Read)
            'One way of transfer over sockets is Using a NetworkStream
            'It provides some useful ways to transfer data
            Dim nfs As NetworkStream = New NetworkStream(sock)

            While rdby < SizeTotal And nfs.CanWrite
                'Read from the File (len contains the number of bytes read)
                len = fin.Read(buffed, 0, buffed.Length)
                'Write the Bytes on the Socket
                nfs.Write(buffed, 0, len)
                'Increase the bytes Read counter
                rdby += len
            End While
            'Display a Message Showing Sucessful File Transfer
            fin.Close()
        Catch ed As Exception
            Console.WriteLine("A Exception occured in transfer" + ed.ToString())
            MsgBox(ed.ToString)
        End Try

Partie qui recoit :

 Private Sub CLIENT_DOWNLOADING(ByVal sock As Socket, ByVal SizeTotale As Long, ByVal path As String)
        Dim fout As FileStream = New FileStream("C:" & path, FileMode.Create, FileAccess.Write)
        Dim nfs As NetworkStream = New NetworkStream(sock)

        Dim ByteLues As Integer
        Dim buffer() As Byte = New Byte(4096) {}

        Invoke(New PbInit(AddressOf Initialisation), CInt(SizeTotale), True)

        Timer1.Enabled = True
        Timer1.Start()

        StartTime = Date.Now.Ticks

        Try
            'loop till the Full bytes have been read
            While rby < SizeTotale
                'Read from the Network Stream
                ByteLues = nfs.Read(buffer, 0, buffer.Length)
                fout.Write(buffer, 0, ByteLues)
                rby += ByteLues
            End While

            fout.Close()

            Timer1.Stop()
            Timer1.Enabled = False

            Client.Send("SendComplete")
            Invoke(New PbInit(AddressOf Initialisation), CInt(SizeTotale), False)
        Catch ed As Exception
            MessageBox.Show(ed.Message)
        End Try
    End Sub

Les deux procédures sont apellés dans l'event Do_Work du controle (pas le meme ^^)

et j'ai des problèmes dans la reception : le stream ne recoit pas tout les bytes envoyés ! si j'enlève le BGW, camarche nickel :)

Dommage j'aurais bien aimé utilisé ce controle mais j'ai peut etre fais une erreur...
0

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

Posez votre question
fdiedler2000 Messages postés 383 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 1 décembre 2008
21 mars 2007 à 23:52
Autre question indépendante de la première :

Pourquoi mon application freeze quand j'execute une procédure
longue (deserialisation d'une treeview) dans un backgroundworker ??


Pour infos, la désérialisation est longue car j'ai que 2 Nodes principaux et dedans y'a enormement de "sous nodes"...


Pourtant ca devrais pas bloquer l'application ?
0
Rejoignez-nous