Précédent   Forum du club des développeurs et IT Pro > Dotnet > Général Dotnet > Framework .NET
Framework .NET Vos questions relatives à l'utilisation des différents Framework .NET
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 08/11/2012, 19h37   #1
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Par défaut [VB.NET] BackgroundWorker trés lent

Je viens de mettre en place un BackgroundWorkerpour gérer une partie de mon code (en vb.net) qui est très longue.
La fonction que j'utilisais avant a été transposée dans une fonction déclenchée par l'event BackgroundWorker.DoWork
J'ai aussi mis en place un BackgroundWorker.ProgressChanged pour suivre la progression de la tache, ainsi que BackgroundWorker.RunWorkerCompleted pour gérer la fin.

Or j'ai remarqué que la même tache exécutée dans mon BackgroundWorker est sensiblement plus longue (X10) par rapport à la même tache dans mon thread principal.

J'ai essayé de commenter la ligne BackgroundWorker.ReportProgress() , mais cela n'y a rien changé.

Est-ce que j'ai loupé quelque chose?
Est-ce que les BackgroundWorker sont par nature plus lents?
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/11/2012, 22h56   #2
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 351
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 351
Points : 2 867
Points : 2 867
Envoyer un message via MSN à GuruuMeditation
Il ne devrait pas y avoir de différences. Tu fais quoi dans le BackgroundWorker?
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2012, 10h29   #3
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Citation:
Envoyé par GuruuMeditation Voir le message
Il ne devrait pas y avoir de différences. Tu fais quoi dans le BackgroundWorker?
La même chose que je faisais dans le thread principal avant :
Je liste de façon récursive les fichiers contenus dans un répertoire ainsi que ses sous-répertoires, et je reporte ça dans une bdd mysql.
Est-ce que le fait que 2 threads (principal + BackgroundWorker) accèdent à la même bdd en même temps peut ralentir chacun d'eux?
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2012, 12h26   #4
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 351
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 351
Points : 2 867
Points : 2 867
Envoyer un message via MSN à GuruuMeditation
Est-ce que tu as essaye de mesurer, dans le backgroundworker quelle partie prend plus de temps? Avec un profileur, par exemple.
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2012, 15h24   #5
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Je viens de faire plusieurs tests avec le BackgroundWorker, et même un thread à part pour évaluer le temps nécessaire à l’exécution de mon script.
En fait le report en bdd des résultats au fil de l'eau prends pas mal de temps.
Mais ce qui en prend encore plus c'est le fait de tester la disponibilité du fichier (est-ce qu'il est déjà ouvert dans un autre programme ou pas) ainsi que la récupération d'infos comme sa date de création....
Je vais continuer mes tests pour avoir un temps d’exécution via le BackgroundWorker par apport à la même exécution dans le thread principal...
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/11/2012, 00h32   #6
sisqo60
Membre Expert
 
Avatar de sisqo60
 
Homme
Consultant informatique
Inscription : février 2006
Messages : 731
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : février 2006
Messages : 731
Points : 1 150
Points : 1 150
Bonsoir,

Un bout de code vaut mieux qu' un long discours. Envoie les 2 codes et on pourra éventuellement trouver ce qui ne va pas. Sinon tu as utilisé directory.getfiles ou enumeratefiles?
__________________
Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

N'oubliez pas de avant de
Pas de question techniques par MP, c'est contre la philosophie du forum
sisqo60 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/11/2012, 15h24   #7
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Au vu des résultats que j'obtiens, je pense que je vais surement changer la construction de mon code, mais je vous laisse juger :

J'ai fais 3 tests :
1) avec un backgroundworker qui exécute la même fonction + une progress barre et un label qui indique le %tage d'avancement
2) avec un vrai autre thread qui exécute la même fonction + une progress barre et un label qui indique le %tage d'avancement
3) dans le thread principal, comme actuellement (par exemple quand on appuie sur un bouton)

Attention dans le cas d'un thread en plus, le thread principal continue à exécuter des fonction/requêtes mysql en même temps

J'ai pris un rep contenant 4112 fichiers répartis dans plus de 100 rep pour un total de plusieurs Go afin de tester la rapidité des différentes solutions.

thread principal
simple 2'36''
sans report bdd 17''
sans report bdd, ni test dispo 5''

BackgroundWorker
simple 5'
sans report progress 5'09''
sans report bdd 3'08''

Thread secondaire
simple 4'49''
sans report bdd 1'35''
sans report bdd, ni test dispo 5''

Mon code ressemble à ça (cas du thread secondaire, pour le reste il suffit de lancer la fonction directement à partir du BGW ou du thread principal, en changeantce qui est propre à chacun) :
Code :
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 
    Private Sub LaunchListMediaThread()
        NewMediaToList = False
        Dim Medias As String = ""
        Dim count As Integer = 0
 
        RemplListMediasThread(FilePath, Medias, count)
        If Medias.Length > 0 Then Medias = Medias.Remove(0, 1)
        MediaTab_Temp = Medias.Split("|")
    End Sub
 
 
    Sub RemplListMediasThread(ByVal RepPere As String, ByRef MediaConcatString As String, ByRef count_avancement As Integer)
        Application.DoEvents()
 
        Dim ListOfRep() As String = Directory.GetDirectories(RepPere)
 
        For indexrep = 0 To ListOfRep.Length - 1
            RemplListMediasThread(ListOfRep(indexrep), MediaConcatString, count_avancement)
        Next
 
        Dim ListOfFiles() As String = System.IO.Directory.GetFileSystemEntries(RepPere, "*.*")
 
        For indexfile = 0 To ListOfFiles.Length - 1
            count_avancement += 1
 
            SetLabelText_ThreadSafe(Me.LabelMedia, count_avancement)
            SetPBValue_ThreadSafe(Me.MediaProgressBar, count_avancement)
 
            Try
                Dim DateCreation As Date = FileDateTime(ListOfFiles(indexfile))
                Dim DiffDate As Integer = DateDiff(DateInterval.Minute, DateCreation, Now)
 
                If FileOk(ListOfFiles(indexfile),DiffDate) Then
                    MediaConcatString = MediaConcatString & "|" & ListOfFiles(indexfile)
                   AddToMediaTableBackThread(Path.GetFileName(ListOfFiles(indexfile)), "1", DateCreation.ToString("yyyy-MM-dd H:mm:ss"))
                   End If
            Catch ex As Exception
 
            End Try
 
            Application.DoEvents()
        Next
    End Sub
 
 
    Sub AddToMediaTableBackThread(ByVal MediaFileName As String, ByVal Statut As String, ByVal DateModif As String)
        Dim MySqlString As String = "INSERT INTO " & MysqlPrefixTable & "medias (`media` ,`statut`, `filedate`) VALUES " & " ('" & MediaFileName & _
                                   "', '" & Statut & "', '" & DateModif & "')" & " ON DUPLICATE KEY UPDATE statut='" & Statut & "', filedate='" & DateModif & "';"
        Dim MyCommand As New MySqlCommand
        Dim MediaMysqlConn As New MySqlConnection
        MediaMysqlConn.ConnectionString = MyConnectionString
        MyCommand.Connection = MediaMysqlConn
        MyCommand.CommandText = MySqlString
 
        Try
            MediaMysqlConn.Open()
            MyCommand.ExecuteNonQuery()
            MediaMysqlConn.Close()
        Catch myerror As MySqlException
 
        End Try
 
        MyCommand.Dispose()
    End Sub
 
 
 
    Delegate Sub SetPBValue_Delegate(ByVal [PB] As ProgressBar, ByVal [value] As Integer)
 
    Private Sub SetPBValue_ThreadSafe(ByVal [PB] As ProgressBar, ByVal [value] As Integer)
        Dim pourcent As Integer = 0
        pourcent = CInt([value] * 100 / (TotalPrecendent + 2))
        If pourcent > 100 Then
            pourcent = 100
        ElseIf pourcent < 0 Then
            pourcent = 0
        End If
 
        If [PB].InvokeRequired Then
            Dim MyDelegate As New SetPBValue_Delegate(AddressOf SetPBValue_ThreadSafe)
            Me.Invoke(MyDelegate, New Object() {[PB], [value]})
        Else
            [PB].Value = pourcent
        End If
    End Sub
J'ai simplifié plusieurs choses, comme FileOk qui teste si le fichier n'est pas utilisé ailleurs (en faisant une tentative de renommage) ou si sa copie est bien terminée...
Pour les tests, j'ai retiré la gestion des exceptions pour simplifier.

La conclusion est quand même que pour l’exécution du MÊME code dans un thread en plus, avec les mêmes paramètres, cela prends:
- 5 minutes avec le Backgroundworker
- 4'49'' avec le thread de Threading.Thread
alors que dans le thread principal cela prend 2'36.

D’où ma question sur la rapidité des thread secondaires ET/OU si le fait de faire en même temps des requêtes dans un thread en parallèle peut ralentir un autre thread...
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 23h52   #8
Graffito
Expert Confirmé Sénior
 
Avatar de Graffito
 
Inscription : janvier 2006
Messages : 5 390
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 5 390
Points : 6 036
Points : 6 036
Il me semble probable que la perte de performance vienne de l'utilisation de Application.DoEvents() normalement inutile si on utilise un BackGroundWorker (pour le multithread, plutôt utiliser un Invoke pour mettre à jour la form)
__________________
" Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson
Graffito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 15h22   #9
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Citation:
Envoyé par Graffito Voir le message
Il me semble probable que la perte de performance vienne de l'utilisation de Application.DoEvents() normalement inutile si on utilise un BackGroundWorker (pour le multithread, plutôt utiliser un Invoke pour mettre à jour la form)
C'était une bonne piste, mais j'ai fait les tests avec et sans Application.DoEvents() et la fonction prends autant de temps...
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 18h04   #10
Graffito
Expert Confirmé Sénior
 
Avatar de Graffito
 
Inscription : janvier 2006
Messages : 5 390
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 5 390
Points : 6 036
Points : 6 036
Lorsque que tu ouvre le gestionnaire de tâche pour observer l'utilisation des processeurs, quel sont les taux d'utilisation des differents processeurs ?
__________________
" Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson
Graffito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 18h47   #11
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Citation:
Envoyé par Graffito Voir le message
Lorsque que tu ouvre le gestionnaire de tâche pour observer l'utilisation des processeurs, quel sont les taux d'utilisation des differents processeurs ?
7-12% pendant l'éxécution du thread secondaire
1-7% sinon
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 22h46   #12
sisqo60
Membre Expert
 
Avatar de sisqo60
 
Homme
Consultant informatique
Inscription : février 2006
Messages : 731
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : février 2006
Messages : 731
Points : 1 150
Points : 1 150
Bonjour,

Citation:
Envoyé par Morphee_ Voir le message
Je liste de façon récursive les fichiers contenus dans un répertoire ainsi que ses sous-répertoires, et je reporte ça dans une bdd mysql.
Est-ce que le fait que 2 threads (principal + BackgroundWorker) accèdent à la même bdd en même temps peut ralentir chacun d'eux?
Maintenant qu'on a écarté les problèmes de performance de code, en relisant les réponses depuis le début, il y a un point sur lequel tu as insisté et auquel nous n'avons pas répondu, oui si tes deux threads font des modifications en base de données sur la même table, les deux threads peuvent être pénalisés.

Désolé de ne pas avoir tilté plus tôt...
__________________
Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

N'oubliez pas de avant de
Pas de question techniques par MP, c'est contre la philosophie du forum
sisqo60 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 23h30   #13
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Citation:
Envoyé par sisqo60 Voir le message
Bonjour,

Maintenant qu'on a écarté les problèmes de performance de code, en relisant les réponses depuis le début, il y a un point sur lequel tu as insisté et auquel nous n'avons pas répondu, oui si tes deux threads font des modifications en base de données sur la même table, les deux threads peuvent être pénalisés.

Désolé de ne pas avoir tilté plus tôt...
Alors, ça me parait assez logique, mais sans aucune requête en bdd, j'ai aussi une différence de temps d’exécution....
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2012, 09h06   #14
sisqo60
Membre Expert
 
Avatar de sisqo60
 
Homme
Consultant informatique
Inscription : février 2006
Messages : 731
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : février 2006
Messages : 731
Points : 1 150
Points : 1 150
Une différence de quel ordre? Tu seras pénalisé aussi si tu lis des fichiers sur le disque, sauf si tu as un disque dur SSD, tout dépend de la quantité et de la taille des fichiers que tu lis. Ça dépend aussi du fait que ton disque dur soit ou non defragmenté, du cache de ton disque dur... bref ça devient compliqué du fait des paramètres à prendre en compte...
__________________
Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

N'oubliez pas de avant de
Pas de question techniques par MP, c'est contre la philosophie du forum
sisqo60 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2012, 10h21   #15
Morphee_
Invité régulier
 
Inscription : février 2011
Messages : 27
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 27
Points : 9
Points : 9
Citation:
Envoyé par sisqo60 Voir le message
Une différence de quel ordre? Tu seras pénalisé aussi si tu lis des fichiers sur le disque, sauf si tu as un disque dur SSD, tout dépend de la quantité et de la taille des fichiers que tu lis. Ça dépend aussi du fait que ton disque dur soit ou non defragmenté, du cache de ton disque dur... bref ça devient compliqué du fait des paramètres à prendre en compte...
Bah cf plus haut, sans éxécuter la fonction AddToMediaTableBackThread :
- thread principal : 17''
- thread secondaire 1'37''
- backgroundworker 3'08''.
Certes, je n'ai fait qu'une mesure et pas plusieurs pour moyenner, mais il y a quand même une grosse différence dans l'ordre de grandeur !
Pour mes tests, se sont plutôt des "petits" fichiers, mais pour mon application pratique ça sera des fichiers assez gros (20-300Mo).
Je suis d'accord que tous ces paramètres entrent en compte, mais s'ils sont les mêmes à chaque fois, pourquoi un thread secondaire et le thread principal n'ont pas les mêmes perf, ça me parait anormal....
Morphee_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 03h17.


 
 
 
 
Partenaires

Hébergement Web