OVH Cloud OVH Cloud

pb de thread

9 réponses
Avatar
Chris
bonjour,
je rencontre un petit pb avec les thread, je souhaiterai faire patienter
un thread principal pendant qu'un thread secondaire travaille. Comment
faire?

explication:

j'ai une form principale avec un bouton et un textbox, qd je clique sur
ce bouton ca ouvre une autre form avec un listview. Ce que j'aimerai
c'est que tant que l'utilisateur n'a pas choisi une ligne du listview le
thread de form principale (bouton + textbox) attende, ensuite une fois
le click sur le listview effectué je souhaite que le textbox prenne la
valeur du listview

j'ai teste différentes méthodes mais ce me pousse le processeur a 100%
lorsque j'utilise Application.DoEvents et plante si je fait dormir le
thread.

merci

9 réponses

Avatar
Patrick Philippot
Chris wrote:
bonjour,
je rencontre un petit pb avec les thread, je souhaiterai faire
patienter un thread principal pendant qu'un thread secondaire
travaille. Comment faire?



Bonjour,

MonThread.Join permet de mettre le thread appelant en attente sur
MonThread. Le thread appelant sera réveillé quand MonThread se
terminera.

Si le thread principal doit être réveillé avant que MonThread ne se
termine, alors synchronisez le thread principal sur un objet de type
System.Threading.AutoResetEvent ou System.Threading.ManualResetEvent
visiblme depuis les deux forms (plutôt AutoReset dans votre cas) et
faites un Set() sur l'objet Event dans le thread secondaire quand les
conditions de libération du thread principal sont réunies.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Chris
Patrick Philippot a écrit :
Chris wrote:

bonjour,
je rencontre un petit pb avec les thread, je souhaiterai faire
patienter un thread principal pendant qu'un thread secondaire
travaille. Comment faire?




Bonjour,

MonThread.Join permet de mettre le thread appelant en attente sur
MonThread. Le thread appelant sera réveillé quand MonThread se
terminera.

Si le thread principal doit être réveillé avant que MonThread ne se
termine, alors synchronisez le thread principal sur un objet de type
System.Threading.AutoResetEvent ou System.Threading.ManualResetEvent
visiblme depuis les deux forms (plutôt AutoReset dans votre cas) et
faites un Set() sur l'objet Event dans le thread secondaire quand les
conditions de libération du thread principal sont réunies.




mais comment puis je faire pour demarrer mon nouveau formulaire sur un
autre thread?
Avatar
Patrick Philippot
Chris wrote:
mais comment puis je faire pour demarrer mon nouveau formulaire sur un
autre thread?



Pour démarrer un second UI-thread:

1. Instanciez et démarrer un nouveau thread qui sera le second UI-thread

2. Dans ce thread ajoutez un gestionnaire pour l'événement
Application.ThreadExit avec AddHandler.

3. Instanciez la seconde Form (SecondForm) qui doit être associée à ce
nouveau thread.

4. Appelez (depuis le thread) Application.Run(SecondForm), ce qui va
démarrer une nouvelle boucle de messages sur ce thread et afficher la
Form.

5. Quand le gestionnaire de l'événement Application.ThreadExit sera
appelé:

SecondForm.Close
Application.ExitThread

(crédit : Klaus Löffelmann)

Voir également ces articles qui vous apporteront quelques
éclaircissements sur cette question qui peut devenir complexe.

http://msdn.microsoft.com/msdnmag/issues/04/05/BasicInstincts/
http://www.developerfusion.com/show/4595/1/

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Chris
Patrick Philippot a écrit :
Chris wrote:

mais comment puis je faire pour demarrer mon nouveau formulaire sur un
autre thread?




Pour démarrer un second UI-thread:

1. Instanciez et démarrer un nouveau thread qui sera le second UI-thread

2. Dans ce thread ajoutez un gestionnaire pour l'événement
Application.ThreadExit avec AddHandler.

3. Instanciez la seconde Form (SecondForm) qui doit être associée à ce
nouveau thread.

4. Appelez (depuis le thread) Application.Run(SecondForm), ce qui va
démarrer une nouvelle boucle de messages sur ce thread et afficher la
Form.

5. Quand le gestionnaire de l'événement Application.ThreadExit sera
appelé:

SecondForm.Close
Application.ExitThread

(crédit : Klaus Löffelmann)

Voir également ces articles qui vous apporteront quelques
éclaircissements sur cette question qui peut devenir complexe.

http://msdn.microsoft.com/msdnmag/issues/04/05/BasicInstincts/
http://www.developerfusion.com/show/4595/1/




desole mais pourriez vous coder ce que vous avez ecrit car la je suis
completement perdu
merci
Avatar
Patrick Philippot
Chris wrote:
desole mais pourriez vous coder ce que vous avez ecrit car la je suis
completement perdu



OK. Mais il faut que je pense à démarrer mon weekend. Je fais ça dès que
je peux...

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Chris
Patrick Philippot a écrit :
Chris wrote:

desole mais pourriez vous coder ce que vous avez ecrit car la je suis
completement perdu




OK. Mais il faut que je pense à démarrer mon weekend. Je fais ça dès que
je peux...



ok merci
Avatar
Patrick Philippot
Bonjour,

Vous trouverez ci-dessous une exemple de code montrant comment démarrer
une Form sur un thread secondaire et comment mettre le thread principal
en attente sur ce thread via un Join.

J'attire cependant votre attention sur le fait que gérer des Forms sur
des threads multiples ne fait en général que compliquer la gestion du
programme. Votre approche me paraît bien compliquée pour un problème
somme toute trivial.

1. Notez que si vous utilisez Join (c-à-d, si vous mettez le thread
principal en attente sur le thread secondaire), votre thread principal
ne peut plus traiter ses propres messages. Donc la fenêtre n'est plus
rafraîchie et son interface est désactivée (enlevez les commentaires
dans le code pour voir ce que ça donne - pas très élégant).

2. Ce que vous décrivez comme comportement souhaité ressemble plutôt à
l'utilisation d'une Form modale: la fenêtre principale est bloquée
jusqu'à ce que la Form modale se termine. L'utilisation de ShowDialog me
semble donc plus adaptée:

frm2 = New Form2
frm2.ShowDialog()

Tant que frm2 n'est pas fermée, aucune action utilisateur ne peut avoir
lieu dans frm1. Il me semble que c'est ce que vous souhaitez.

Notez bien que ce n'est pas parce que frm2 aura été fermée que l'objet
frm2 n'existe plus et que vous ne pouvez plus accéder à ses propriétés
(si c'est le point qui vous chagrine). C'est une erreur répandue que de
confondre la fenêtre physique (qui peut ou non exister à l'écran) et
l'instance de Form qui représente cet objet. L'objet Form peut vivre
même si la fenêtre Windows au sens physique du terme n'existe pas.

Est-ce plus clair?

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr

Imports System.threading

Public Class Form1
Inherits System.Windows.Forms.Form

Private frm2 As Form2

+#Region " Windows Form Designer generated code

Private Sub ThreadExitHandler(ByVal sender As Object, ByVal e As
EventArgs)
If Not frm2 Is Nothing Then
frm2.Close()
Application.ExitThread()
RemoveHandler Application.ThreadExit, AddressOf
ThreadExitHandler
' Nécessaire pour éviter l'appel sur chaque fin de thread y
compris
' pour le thread principal
End If
End Sub

Private Sub WorkThread()
frm2 = New Form2
Application.Run(frm2)
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

AddHandler Application.ThreadExit, AddressOf ThreadExitHandler
' Le code ci-dessus n'est pas absolument indispensable mais plus
' plus prudent au cas où le thread se termine autrement que par
' une fermeture de la Form2

Dim newThread As Thread = New Thread(AddressOf WorkThread)
newThread.Start()
' Mise en attente sur le thread secondaire
'newThread.Join()
'MsgBox("Le thread secondaire est terminé")

End Sub

End Class
Avatar
Chris
Patrick Philippot a écrit :
Bonjour,

Vous trouverez ci-dessous une exemple de code montrant comment démarrer
une Form sur un thread secondaire et comment mettre le thread principal
en attente sur ce thread via un Join.

J'attire cependant votre attention sur le fait que gérer des Forms sur
des threads multiples ne fait en général que compliquer la gestion du
programme. Votre approche me paraît bien compliquée pour un problème
somme toute trivial.

1. Notez que si vous utilisez Join (c-à-d, si vous mettez le thread
principal en attente sur le thread secondaire), votre thread principal
ne peut plus traiter ses propres messages. Donc la fenêtre n'est plus
rafraîchie et son interface est désactivée (enlevez les commentaires
dans le code pour voir ce que ça donne - pas très élégant).

2. Ce que vous décrivez comme comportement souhaité ressemble plutôt à
l'utilisation d'une Form modale: la fenêtre principale est bloquée
jusqu'à ce que la Form modale se termine. L'utilisation de ShowDialog me
semble donc plus adaptée:

frm2 = New Form2
frm2.ShowDialog()

Tant que frm2 n'est pas fermée, aucune action utilisateur ne peut avoir
lieu dans frm1. Il me semble que c'est ce que vous souhaitez.

Notez bien que ce n'est pas parce que frm2 aura été fermée que l'objet
frm2 n'existe plus et que vous ne pouvez plus accéder à ses propriétés
(si c'est le point qui vous chagrine). C'est une erreur répandue que de
confondre la fenêtre physique (qui peut ou non exister à l'écran) et
l'instance de Form qui représente cet objet. L'objet Form peut vivre
même si la fenêtre Windows au sens physique du terme n'existe pas.

Est-ce plus clair?



faisant confiance a votre expérience voici mon probleme, peut etre
verrez vous une autre solution.

j'ai un formulaire a un Textbox et un bouton, quand je clique sur ce
bouton un autre formulaire apparait avec un listview conta=enant des
lignes. Qd je clique sur le listview je souhaiterais que le textbox de
la form1 se remplisse de la valeur du listview de la form2.
J'ai teste une boucle while avec un boolean qui passe a vrai qd je
selectionne un ligne dans le listview mais cela me pousse le processeur
a 100% meme si je rajoute Application.DoEvents. Voyez vous une autre
solution?

merci
Avatar
Chris
Patrick Philippot a écrit :
Bonjour,

Vous trouverez ci-dessous une exemple de code montrant comment démarrer
une Form sur un thread secondaire et comment mettre le thread principal
en attente sur ce thread via un Join.

J'attire cependant votre attention sur le fait que gérer des Forms sur
des threads multiples ne fait en général que compliquer la gestion du
programme. Votre approche me paraît bien compliquée pour un problème
somme toute trivial.

1. Notez que si vous utilisez Join (c-à-d, si vous mettez le thread
principal en attente sur le thread secondaire), votre thread principal
ne peut plus traiter ses propres messages. Donc la fenêtre n'est plus
rafraîchie et son interface est désactivée (enlevez les commentaires
dans le code pour voir ce que ça donne - pas très élégant).

2. Ce que vous décrivez comme comportement souhaité ressemble plutôt à
l'utilisation d'une Form modale: la fenêtre principale est bloquée
jusqu'à ce que la Form modale se termine. L'utilisation de ShowDialog me
semble donc plus adaptée:

frm2 = New Form2
frm2.ShowDialog()

Tant que frm2 n'est pas fermée, aucune action utilisateur ne peut avoir
lieu dans frm1. Il me semble que c'est ce que vous souhaitez.

Notez bien que ce n'est pas parce que frm2 aura été fermée que l'objet
frm2 n'existe plus et que vous ne pouvez plus accéder à ses propriétés
(si c'est le point qui vous chagrine). C'est une erreur répandue que de
confondre la fenêtre physique (qui peut ou non exister à l'écran) et
l'instance de Form qui représente cet objet. L'objet Form peut vivre
même si la fenêtre Windows au sens physique du terme n'existe pas.

Est-ce plus clair?



merci beaucoup ne tenez pas compte du dernier message mon ordi a plante
entre tps :(

MERCI :)