Voici mon problème. En travaillant sur le multithreading, je suis arrivé à me
préoccuper du marshaling à cause d'un exemple de gestion multithreads
récupéré sur le site Microsotf.FR
(http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp).
C'est en effet à la fin de l'exemple Calculator sur le multithreading, qu'il
est question d'appels marshaling à des contrôles.
L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un
peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être
implémenté lorsqu'un thread secondaire
active une méthode d'un thread principal. Je comprends aussi que la mise en
œuvre de ce marshaling consiste
simplement à déléguer à une méthode asynchrone, la réaction souhaitée en
réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte
une classe MesProcedures qui implémente
2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit un
vecteur de 11 entiers et génére un
événement ResultatComplet qui est pris en charge dans le module appellant
par la procédure événementielle
ResultatDisponible. Le marshaling consiste à faire exécuter le travail de
cette procédure par une méthode déléguée asynchrone.
J'ai donc déclaré un délégué et je remplace l'appel synchrone de la
procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As Integer)
Dim TLocal() As Integer
Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer)
ReDim TLocal(Taille)
TailleLocale = Taille
End Sub
Public Sub UneProc1()
SyncLock TLocal ' Verrouillage de TLocal
For i As Integer = 0 To TailleLocale
Thread.Sleep(100)
TLocal(i) = i
Next i
RaiseEvent ResultatComplet(TLocal, TailleLocale)
End SyncLock ' Libèration (après expédition du résultat)
End Sub
Public Sub UneProc2()
SyncLock TLocal ' Verrouillage de TLocal
For i As Integer = 0 To TailleLocale
Thread.Sleep(200)
TLocal(i) = 100 + i
Next i
RaiseEvent ResultatComplet(TLocal, TailleLocale)
End SyncLock ' Libèration (après expédition du résultat)
End Sub
End Class
Voici le code principal qui implémente le marshaling tel que je le comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As
Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf
TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur
As Integer)
For i As Integer = 0 To Longueur
Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit
Next
End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As
Integer)
' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel synchrone
TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel
asynchrone
End Sub
Public Sub Main()
Dim Procedure As New MesProcedures(10)
Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1)
Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2)
AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible
Traitement1.Start() ' Doit fournir les valeurs de 0 à 10
Traitement2.Start() ' Doit fournir les valeurs de 100 à 110
Console.ReadLine() ' Attendre la fin des affichages
End Sub
End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne.
Il y a événtuellement problème si je me suis complètement fourvoyé dans ma
compréhension du marshaling.
Dans ce cas, il serait utile qu'on me dise où j'ai dérapé …
Par contre, il y a réellement problème si ma compréhension et la mise en
œuvre du marshaling sont correctes.
Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce
dispositif comme étant nécessaire alors
que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai
placé des points de mesures
(Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi
effectué les tests en chargeant
les procédures déléguées de traitements supplémentaires (boucle de 1000000
itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le
marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait du
multithreading ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Patrice
A mon avis c'est inutile dans ton code. Note que l'article précise bien "Appels marshaling à des *contrôles*", le problème étant qu'un contrôle ne peut-être manipulé que par le thread qui l'a créé...
Donc le Invoke et utile ou non en fonction de ce que fait le code que tu appelles...
En 2.0, le composant BackgroundWorker peut-être utile...
-- Patrice
"Phil" a écrit dans le message de news:
Voici mon problème. En travaillant sur le multithreading, je suis arrivé à me préoccuper du marshaling à cause d'un exemple de gestion multithreads récupéré sur le site Microsotf.FR (http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp). C'est en effet à la fin de l'exemple Calculator sur le multithreading, qu'il est question d'appels marshaling à des contrôles. L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être implémenté lorsqu'un thread secondaire active une méthode d'un thread principal. Je comprends aussi que la mise en ouvre de ce marshaling consiste simplement à déléguer à une méthode asynchrone, la réaction souhaitée en réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte une classe MesProcedures qui implémente 2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit un vecteur de 11 entiers et génére un événement ResultatComplet qui est pris en charge dans le module appellant par la procédure événementielle ResultatDisponible. Le marshaling consiste à faire exécuter le travail de cette procédure par une méthode déléguée asynchrone. J'ai donc déclaré un délégué et je remplace l'appel synchrone de la procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As Integer)
Dim TLocal() As Integer Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer) ReDim TLocal(Taille) TailleLocale = Taille End Sub
Public Sub UneProc1() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(100) TLocal(i) = i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub
Public Sub UneProc2() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(200) TLocal(i) = 100 + i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub End Class
Voici le code principal qui implémente le marshaling tel que je le comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) For i As Integer = 0 To Longueur Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit Next End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) ' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel synchrone TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel asynchrone End Sub
Public Sub Main() Dim Procedure As New MesProcedures(10) Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1) Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2) AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible Traitement1.Start() ' Doit fournir les valeurs de 0 à 10 Traitement2.Start() ' Doit fournir les valeurs de 100 à 110 Console.ReadLine() ' Attendre la fin des affichages End Sub End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne. Il y a événtuellement problème si je me suis complètement fourvoyé dans ma compréhension du marshaling. Dans ce cas, il serait utile qu'on me dise où j'ai dérapé .
Par contre, il y a réellement problème si ma compréhension et la mise en ouvre du marshaling sont correctes. Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce dispositif comme étant nécessaire alors que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai placé des points de mesures (Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi effectué les tests en chargeant les procédures déléguées de traitements supplémentaires (boucle de 1000000 itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait du multithreading ?
A mon avis c'est inutile dans ton code. Note que l'article précise bien
"Appels marshaling à des *contrôles*", le problème étant qu'un contrôle ne
peut-être manipulé que par le thread qui l'a créé...
Donc le Invoke et utile ou non en fonction de ce que fait le code que tu
appelles...
En 2.0, le composant BackgroundWorker peut-être utile...
--
Patrice
"Phil" <Phil@discussions.microsoft.com> a écrit dans le message de news:
54048B4E-0D77-425B-8C40-56E8301B60AA@microsoft.com...
Voici mon problème. En travaillant sur le multithreading, je suis arrivé à
me
préoccuper du marshaling à cause d'un exemple de gestion multithreads
récupéré sur le site Microsotf.FR
(http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp).
C'est en effet à la fin de l'exemple Calculator sur le multithreading,
qu'il
est question d'appels marshaling à des contrôles.
L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un
peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être
implémenté lorsqu'un thread secondaire
active une méthode d'un thread principal. Je comprends aussi que la mise
en
ouvre de ce marshaling consiste
simplement à déléguer à une méthode asynchrone, la réaction souhaitée en
réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte
une classe MesProcedures qui implémente
2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit
un
vecteur de 11 entiers et génére un
événement ResultatComplet qui est pris en charge dans le module appellant
par la procédure événementielle
ResultatDisponible. Le marshaling consiste à faire exécuter le travail de
cette procédure par une méthode déléguée asynchrone.
J'ai donc déclaré un délégué et je remplace l'appel synchrone de la
procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As
Integer)
Dim TLocal() As Integer
Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer)
ReDim TLocal(Taille)
TailleLocale = Taille
End Sub
Public Sub UneProc1()
SyncLock TLocal ' Verrouillage de TLocal
For i As Integer = 0 To TailleLocale
Thread.Sleep(100)
TLocal(i) = i
Next i
RaiseEvent ResultatComplet(TLocal, TailleLocale)
End SyncLock ' Libèration (après expédition du résultat)
End Sub
Public Sub UneProc2()
SyncLock TLocal ' Verrouillage de TLocal
For i As Integer = 0 To TailleLocale
Thread.Sleep(200)
TLocal(i) = 100 + i
Next i
RaiseEvent ResultatComplet(TLocal, TailleLocale)
End SyncLock ' Libèration (après expédition du résultat)
End Sub
End Class
Voici le code principal qui implémente le marshaling tel que je le
comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As
Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf
TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur
As Integer)
For i As Integer = 0 To Longueur
Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit
Next
End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As
Integer)
' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel
synchrone
TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel
asynchrone
End Sub
Public Sub Main()
Dim Procedure As New MesProcedures(10)
Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1)
Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2)
AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible
Traitement1.Start() ' Doit fournir les valeurs de 0 à 10
Traitement2.Start() ' Doit fournir les valeurs de 100 à 110
Console.ReadLine() ' Attendre la fin des affichages
End Sub
End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne.
Il y a événtuellement problème si je me suis complètement fourvoyé dans ma
compréhension du marshaling.
Dans ce cas, il serait utile qu'on me dise où j'ai dérapé .
Par contre, il y a réellement problème si ma compréhension et la mise en
ouvre du marshaling sont correctes.
Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce
dispositif comme étant nécessaire alors
que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai
placé des points de mesures
(Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi
effectué les tests en chargeant
les procédures déléguées de traitements supplémentaires (boucle de 1000000
itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le
marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait
du
multithreading ?
A mon avis c'est inutile dans ton code. Note que l'article précise bien "Appels marshaling à des *contrôles*", le problème étant qu'un contrôle ne peut-être manipulé que par le thread qui l'a créé...
Donc le Invoke et utile ou non en fonction de ce que fait le code que tu appelles...
En 2.0, le composant BackgroundWorker peut-être utile...
-- Patrice
"Phil" a écrit dans le message de news:
Voici mon problème. En travaillant sur le multithreading, je suis arrivé à me préoccuper du marshaling à cause d'un exemple de gestion multithreads récupéré sur le site Microsotf.FR (http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp). C'est en effet à la fin de l'exemple Calculator sur le multithreading, qu'il est question d'appels marshaling à des contrôles. L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être implémenté lorsqu'un thread secondaire active une méthode d'un thread principal. Je comprends aussi que la mise en ouvre de ce marshaling consiste simplement à déléguer à une méthode asynchrone, la réaction souhaitée en réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte une classe MesProcedures qui implémente 2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit un vecteur de 11 entiers et génére un événement ResultatComplet qui est pris en charge dans le module appellant par la procédure événementielle ResultatDisponible. Le marshaling consiste à faire exécuter le travail de cette procédure par une méthode déléguée asynchrone. J'ai donc déclaré un délégué et je remplace l'appel synchrone de la procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As Integer)
Dim TLocal() As Integer Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer) ReDim TLocal(Taille) TailleLocale = Taille End Sub
Public Sub UneProc1() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(100) TLocal(i) = i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub
Public Sub UneProc2() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(200) TLocal(i) = 100 + i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub End Class
Voici le code principal qui implémente le marshaling tel que je le comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) For i As Integer = 0 To Longueur Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit Next End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) ' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel synchrone TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel asynchrone End Sub
Public Sub Main() Dim Procedure As New MesProcedures(10) Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1) Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2) AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible Traitement1.Start() ' Doit fournir les valeurs de 0 à 10 Traitement2.Start() ' Doit fournir les valeurs de 100 à 110 Console.ReadLine() ' Attendre la fin des affichages End Sub End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne. Il y a événtuellement problème si je me suis complètement fourvoyé dans ma compréhension du marshaling. Dans ce cas, il serait utile qu'on me dise où j'ai dérapé .
Par contre, il y a réellement problème si ma compréhension et la mise en ouvre du marshaling sont correctes. Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce dispositif comme étant nécessaire alors que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai placé des points de mesures (Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi effectué les tests en chargeant les procédures déléguées de traitements supplémentaires (boucle de 1000000 itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait du multithreading ?
Phil
Merci Patrice.
J'avais bien capté la nuance "Cotrôle". Aussi ai-je réalisé ensuite les tests avec un "Component" conformément à l'article et les résultats n'étaient pas meilleurs.
En tous cas, tu me confortes dans l'idée que le marshaling n'est pas nécessaire dans ces exmples.
Je ne connais pas encore le BackgroundWorker. Je vais étudier ça.
Phil
()
"Phil" a écrit :
Voici mon problème. En travaillant sur le multithreading, je suis arrivé à me préoccuper du marshaling à cause d'un exemple de gestion multithreads récupéré sur le site Microsotf.FR (http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp). C'est en effet à la fin de l'exemple Calculator sur le multithreading, qu'il est question d'appels marshaling à des contrôles. L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être implémenté lorsqu'un thread secondaire active une méthode d'un thread principal. Je comprends aussi que la mise en œuvre de ce marshaling consiste simplement à déléguer à une méthode asynchrone, la réaction souhaitée en réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte une classe MesProcedures qui implémente 2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit un vecteur de 11 entiers et génére un événement ResultatComplet qui est pris en charge dans le module appellant par la procédure événementielle ResultatDisponible. Le marshaling consiste à faire exécuter le travail de cette procédure par une méthode déléguée asynchrone. J'ai donc déclaré un délégué et je remplace l'appel synchrone de la procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As Integer)
Dim TLocal() As Integer Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer) ReDim TLocal(Taille) TailleLocale = Taille End Sub
Public Sub UneProc1() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(100) TLocal(i) = i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub
Public Sub UneProc2() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(200) TLocal(i) = 100 + i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub End Class
Voici le code principal qui implémente le marshaling tel que je le comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) For i As Integer = 0 To Longueur Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit Next End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) ' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel synchrone TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel asynchrone End Sub
Public Sub Main() Dim Procedure As New MesProcedures(10) Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1) Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2) AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible Traitement1.Start() ' Doit fournir les valeurs de 0 à 10 Traitement2.Start() ' Doit fournir les valeurs de 100 à 110 Console.ReadLine() ' Attendre la fin des affichages End Sub End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne. Il y a événtuellement problème si je me suis complètement fourvoyé dans ma compréhension du marshaling. Dans ce cas, il serait utile qu'on me dise où j'ai dérapé …
Par contre, il y a réellement problème si ma compréhension et la mise en œuvre du marshaling sont correctes. Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce dispositif comme étant nécessaire alors que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai placé des points de mesures (Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi effectué les tests en chargeant les procédures déléguées de traitements supplémentaires (boucle de 1000000 itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait du multithreading ?
Merci Patrice.
J'avais bien capté la nuance "Cotrôle". Aussi ai-je réalisé ensuite les
tests avec un "Component" conformément à l'article et les résultats n'étaient
pas meilleurs.
En tous cas, tu me confortes dans l'idée que le marshaling n'est pas
nécessaire dans ces exmples.
Je ne connais pas encore le BackgroundWorker. Je vais étudier ça.
Phil
(phr@fulladsl.be)
"Phil" a écrit :
Voici mon problème. En travaillant sur le multithreading, je suis arrivé à me
préoccuper du marshaling à cause d'un exemple de gestion multithreads
récupéré sur le site Microsotf.FR
(http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp).
C'est en effet à la fin de l'exemple Calculator sur le multithreading, qu'il
est question d'appels marshaling à des contrôles.
L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un
peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être
implémenté lorsqu'un thread secondaire
active une méthode d'un thread principal. Je comprends aussi que la mise en
œuvre de ce marshaling consiste
simplement à déléguer à une méthode asynchrone, la réaction souhaitée en
réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte
une classe MesProcedures qui implémente
2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit un
vecteur de 11 entiers et génére un
événement ResultatComplet qui est pris en charge dans le module appellant
par la procédure événementielle
ResultatDisponible. Le marshaling consiste à faire exécuter le travail de
cette procédure par une méthode déléguée asynchrone.
J'ai donc déclaré un délégué et je remplace l'appel synchrone de la
procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As Integer)
Dim TLocal() As Integer
Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer)
ReDim TLocal(Taille)
TailleLocale = Taille
End Sub
Public Sub UneProc1()
SyncLock TLocal ' Verrouillage de TLocal
For i As Integer = 0 To TailleLocale
Thread.Sleep(100)
TLocal(i) = i
Next i
RaiseEvent ResultatComplet(TLocal, TailleLocale)
End SyncLock ' Libèration (après expédition du résultat)
End Sub
Public Sub UneProc2()
SyncLock TLocal ' Verrouillage de TLocal
For i As Integer = 0 To TailleLocale
Thread.Sleep(200)
TLocal(i) = 100 + i
Next i
RaiseEvent ResultatComplet(TLocal, TailleLocale)
End SyncLock ' Libèration (après expédition du résultat)
End Sub
End Class
Voici le code principal qui implémente le marshaling tel que je le comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As
Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf
TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur
As Integer)
For i As Integer = 0 To Longueur
Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit
Next
End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As
Integer)
' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel synchrone
TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel
asynchrone
End Sub
Public Sub Main()
Dim Procedure As New MesProcedures(10)
Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1)
Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2)
AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible
Traitement1.Start() ' Doit fournir les valeurs de 0 à 10
Traitement2.Start() ' Doit fournir les valeurs de 100 à 110
Console.ReadLine() ' Attendre la fin des affichages
End Sub
End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne.
Il y a événtuellement problème si je me suis complètement fourvoyé dans ma
compréhension du marshaling.
Dans ce cas, il serait utile qu'on me dise où j'ai dérapé …
Par contre, il y a réellement problème si ma compréhension et la mise en
œuvre du marshaling sont correctes.
Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce
dispositif comme étant nécessaire alors
que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai
placé des points de mesures
(Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi
effectué les tests en chargeant
les procédures déléguées de traitements supplémentaires (boucle de 1000000
itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le
marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait du
multithreading ?
J'avais bien capté la nuance "Cotrôle". Aussi ai-je réalisé ensuite les tests avec un "Component" conformément à l'article et les résultats n'étaient pas meilleurs.
En tous cas, tu me confortes dans l'idée que le marshaling n'est pas nécessaire dans ces exmples.
Je ne connais pas encore le BackgroundWorker. Je vais étudier ça.
Phil
()
"Phil" a écrit :
Voici mon problème. En travaillant sur le multithreading, je suis arrivé à me préoccuper du marshaling à cause d'un exemple de gestion multithreads récupéré sur le site Microsotf.FR (http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vbcon/html/vbconwalkthroughsimplemultithreadedcomponent.asp). C'est en effet à la fin de l'exemple Calculator sur le multithreading, qu'il est question d'appels marshaling à des contrôles. L'exemple que j'ai réécrit ci dessous n'est qu'une version francisée et un peu simplifiée de l'exemple de Microsoft.
Ce que je comprends de la technique, c'est que le marshaling doit être implémenté lorsqu'un thread secondaire active une méthode d'un thread principal. Je comprends aussi que la mise en œuvre de ce marshaling consiste simplement à déléguer à une méthode asynchrone, la réaction souhaitée en réponse à l'action du thread secondaire.
Dans cette logique, l'exemple suivant illustre le marshaling. Il comporte une classe MesProcedures qui implémente 2 méthodes Traitement1 et Traitement2. Chacun de ces traitements remplit un vecteur de 11 entiers et génére un événement ResultatComplet qui est pris en charge dans le module appellant par la procédure événementielle ResultatDisponible. Le marshaling consiste à faire exécuter le travail de cette procédure par une méthode déléguée asynchrone. J'ai donc déclaré un délégué et je remplace l'appel synchrone de la procédure d'affichage par son appel asynchrone via le délégué.
Voici le code de la classe.
Imports System.Threading
Public Class MesProcedures
Public Event ResultatComplet(ByRef T() As Integer, ByVal Taille As Integer)
Dim TLocal() As Integer Dim TailleLocale As Integer
Public Sub New(ByVal Taille As Integer) ReDim TLocal(Taille) TailleLocale = Taille End Sub
Public Sub UneProc1() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(100) TLocal(i) = i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub
Public Sub UneProc2() SyncLock TLocal ' Verrouillage de TLocal For i As Integer = 0 To TailleLocale Thread.Sleep(200) TLocal(i) = 100 + i Next i RaiseEvent ResultatComplet(TLocal, TailleLocale) End SyncLock ' Libèration (après expédition du résultat) End Sub End Class
Voici le code principal qui implémente le marshaling tel que je le comprends.
Public Module MonModule
Public Delegate Sub ResultatPresent(ByRef T() As Integer, ByVal L As Integer)
Dim TraitementResultat As New ResultatPresent(AddressOf TraiteResultatDisponible)
Private Sub TraiteResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) For i As Integer = 0 To Longueur Console.Write(T(i).ToString("000") & " ") ' Affichage proprement dit Next End Sub
Private Sub ResultatDisponible(ByRef T() As Integer, ByVal Longueur As Integer) ' TraiteResultatDisponible(T, Longueur) ' Pour test avec appel synchrone TraitementResultat.BeginInvoke(T, Longueur, Nothing, Nothing) 'Appel asynchrone End Sub
Public Sub Main() Dim Procedure As New MesProcedures(10) Dim Traitement1 As New Thread(AddressOf Procedure.UneProc1) Dim Traitement2 As New Thread(AddressOf Procedure.UneProc2) AddHandler Procedure.ResultatComplet, AddressOf ResultatDisponible Traitement1.Start() ' Doit fournir les valeurs de 0 à 10 Traitement2.Start() ' Doit fournir les valeurs de 100 à 110 Console.ReadLine() ' Attendre la fin des affichages End Sub End Module
Bien sûr, jusque là, il n'y a aucun problème et tout fonctionne. Il y a événtuellement problème si je me suis complètement fourvoyé dans ma compréhension du marshaling. Dans ce cas, il serait utile qu'on me dise où j'ai dérapé …
Par contre, il y a réellement problème si ma compréhension et la mise en œuvre du marshaling sont correctes. Car dans ce cas, je ne comprends pas pourquoi Microsoft indique ce dispositif comme étant nécessaire alors que cela fonctionne encore mieux en multithreading sans marshaling !!!
Après avoir programmé l'exemple MicroSoft, avec et sans marshaling, j'y ai placé des points de mesures (Now.TimeOfDay.ToString) de sorte à évaluer les performances. J'ai aussi effectué les tests en chargeant les procédures déléguées de traitements supplémentaires (boucle de 1000000 itérations).
Dans tous les cas (déjà même dans l'exemple MesProcedures ci-dessus), le marshaling provoque une perte de temps.
Alors, voici la question finale : A quoi bon le marshaling quand on fait du multithreading ?