OVH Cloud OVH Cloud

Form et OCX dans différents Tread

9 réponses
Avatar
cyrille
Bonjour,

Je souhaiterais d=E9coupler un application en diff=E9rents threads.

Il s'agit d'un Form (Controleur) qui ouvre un seconde Form (Player) contena=
nt=20
un OCX ShockwaveFlash (Player SWF Flash).
Mon probl=E8me est quand le 1er Form (Controleur) effectue des op=E9rations=
=20
bloquantes (acc=E8s r=E9seaux, longs calculs), les animations de l'OCX du s=
econde=20
Form sont fig=E9es durant le temps de l'op=E9ration.

Je pourrais modifier le Form (Controleur) pour qu'il effectue ses op=E9rati=
ons=20
bloquantes de fa=E7on asynchrone.
Mais dans l'id=E9e du moindre effort, je me demande s'il est possible de jo=
uer le=20
second Form (Player) dans un autre thread.

Et je n'ais aucune id=E9e sur comment faire ...

Et vous ?
Merci d'avance pour vos id=E9es !
cyrille

9 réponses

Avatar
Mr Smith
Bonjour,

Il faut créer une méthode qui lancera ta form
dans un nouveau thread.

Thread thrService = new Thread( this.MaMéthode);

remarque : Si ton deuxième thread utilise des membres
partagés avec ton thread principal il faudra alors utilisé des sections
"lock()"



"cyrille" wrote in message
news:
Bonjour,

Je souhaiterais découpler un application en différents threads.

Il s'agit d'un Form (Controleur) qui ouvre un seconde Form (Player) contenan

t
un OCX ShockwaveFlash (Player SWF Flash).
Mon problème est quand le 1er Form (Controleur) effectue des opérations
bloquantes (accès réseaux, longs calculs), les animations de l'OCX du
seconde
Form sont figées durant le temps de l'opération.

Je pourrais modifier le Form (Controleur) pour qu'il effectue ses opérations
bloquantes de façon asynchrone.
Mais dans l'idée du moindre effort, je me demande s'il est possible de jouer
le
second Form (Player) dans un autre thread.

Et je n'ais aucune idée sur comment faire ...

Et vous ?
Merci d'avance pour vos idées !
cyrille
Avatar
cyrille
In article , says...
Bonjour,

Il faut créer une méthode qui lancera ta form
dans un nouveau thread.

Thread thrService = new Thread( this.MaMéthode);



En fait c'est ce que j'ais essayer avant de poster ici, mais ça ne foncti onne
pas.
Dans la méthode appelée depuis le nouveau thread je fais le new() du fo rm puis
le show() et ensuite pour que la fenêtre reste affichée j'ais mis un
while(from.visible){Sleep(0);}

Et bien c'est pas bon :
- le curseur reste en mode 'sablier'
- Avant ou sans le while() quand je quitte le programme il y a une exceptio n
NullReference. Je pense qu'il s'agit du framework qui n'accède pas correc tement
au handler du form.

Donc je cherche quelle méthode est valide pour ce genre de problème ?

cyrille
Avatar
cyrille
In article , says...
Bonjour,

Il faut créer une méthode qui lancera ta form
dans un nouveau thread.

Thread thrService = new Thread( this.MaMéthode);

remarque : Si ton deuxième thread utilise des membres
partagés avec ton thread principal il faudra alors utilisé des sectio ns
"lock()"




Mais comment faire pour que ce nouveau thread continu d'exister ?

void lancement(){
Thread thrService = new Thread( this.MaMéthode);
}

void MaMéthode(){
Form2 f2 = new Form2();
f2.Show();
// ensuite le thread se termine ...
// comment le faire exister tout en permettant à f2 de traiter les messa ges ?
}

cyrille
Avatar
Paul Bacelar
>"cyrille" wrote in message


news:
In article , says...
Bonjour,

Il faut créer une méthode qui lancera ta form
dans un nouveau thread.

Thread thrService = new Thread( this.MaMéthode);



En fait c'est ce que j'ais essayer avant de poster ici, mais ça ne


fonctionne
pas.
Dans la méthode appelée depuis le nouveau thread je fais le new() du form


puis
le show() et ensuite pour que la fenêtre reste affichée j'ais mis un
while(from.visible){Sleep(0);}




Votre boucle empêche la pompe à message de prendre les évènements des
fenêtres comme les demandes d'affichages.
cf.:
http://msdn.microsoft.com/msdnmag/issues/04/01/BasicInstincts/default.aspx
http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/default.aspx

Un Form.ShowDialog serait beaucoup plus simple

Et bien c'est pas bon :
- le curseur reste en mode 'sablier'



Normal, la fenêtre ne traite pas les messages cf Form.ShowDialog.

- Avant ou sans le while() quand je quitte le programme il y a une


exception
NullReference. Je pense qu'il s'agit du framework qui n'accède pas


correctement
au handler du form.




cf:
http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/default.aspx

Donc je cherche quelle méthode est valide pour ce genre de problème ?

cyrille



--
Paul Bacelar
Avatar
Paul Bacelar
>"cyrille" wrote in message


news:
In article , says...
Bonjour,

Il faut créer une méthode qui lancera ta form
dans un nouveau thread.

Thread thrService = new Thread( this.MaMéthode);

remarque : Si ton deuxième thread utilise des membres
partagés avec ton thread principal il faudra alors utilisé des sections
"lock()"




Mais comment faire pour que ce nouveau thread continu d'exister ?

void lancement(){
Thread thrService = new Thread( this.MaMéthode);
}

void MaMéthode(){
Form2 f2 = new Form2();
f2.Show();



if(f2.ShowDialog()==DialogResult.OK){
...
}

// ensuite le thread se termine ...
// comment le faire exister tout en permettant à f2 de traiter les


messages ?
}

cyrille


Voir aussi la propriété IsBackground de la class Thread.

--
Paul Bacelar
Avatar
cyrille
In article <OqhGk5Q#,
says...
>"cyrille" wrote in message
news:
>In article , says ...
>> Bonjour,
>>
>> Il faut créer une méthode qui lancera ta form
>> dans un nouveau thread.
>>
>> Thread thrService = new Thread( this.MaMéthode);
>
>En fait c'est ce que j'ais essayer avant de poster ici, mais ça ne
fonctionne
>pas.
>Dans la méthode appelée depuis le nouveau thread je fais le new() du form
puis
>le show() et ensuite pour que la fenêtre reste affichée j'ais mis un
>while(from.visible){Sleep(0);}
>

Votre boucle empêche la pompe à message de prendre les évènements des
fenêtres comme les demandes d'affichages.
cf.:
http://msdn.microsoft.com/msdnmag/issues/04/01/BasicInstincts/default.asp x
http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/default.asp x

Un Form.ShowDialog serait beaucoup plus simple

>Et bien c'est pas bon :
>- le curseur reste en mode 'sablier'

Normal, la fenêtre ne traite pas les messages cf Form.ShowDialog.

>- Avant ou sans le while() quand je quitte le programme il y a une
exception
>NullReference. Je pense qu'il s'agit du framework qui n'accède pas
correctement
>au handler du form.
>

cf:
http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/default.asp x

>Donc je cherche quelle méthode est valide pour ce genre de problème ?
>
>cyrille




Merci Paul pour tous ces liens que je vais lire après cette précision :

Je souhaite avoir 2 fenêtres avec chacune son thread d'exécution.
Les 2 fenêtres doivent être accessibles par l'utilisateur, donc pas de
ShowDialog.
La 1ere fenêtre est un form 'normal' avec des controls, la seconde compor te un
ocx Shockwave Flash. Elle nécessite un second thread pour que les animati ons
Flash ne soient pas stoppées lorsque la 1ere fenêtre exéxute un calcu l.

Peut être as tu d'autres liens ou d'autres explications plus adaptés à cette
configuration.

Merci
Cyrille
Avatar
Paul Bacelar
>"cyrille" wrote in message


news:
In article <OqhGk5Q#,
says...
>"cyrille" wrote in message
news:
>In article ,




says...
>> Bonjour,
>>
>> Il faut créer une méthode qui lancera ta form
>> dans un nouveau thread.
>>
>> Thread thrService = new Thread( this.MaMéthode);
>
>En fait c'est ce que j'ais essayer avant de poster ici, mais ça ne
fonctionne
>pas.
>Dans la méthode appelée depuis le nouveau thread je fais le new() du




form
puis
>le show() et ensuite pour que la fenêtre reste affichée j'ais mis un
>while(from.visible){Sleep(0);}
>

Votre boucle empêche la pompe à message de prendre les évènements des
fenêtres comme les demandes d'affichages.
cf.:





http://msdn.microsoft.com/msdnmag/issues/04/01/BasicInstincts/default.aspx





http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/default.aspx

Un Form.ShowDialog serait beaucoup plus simple

>Et bien c'est pas bon :
>- le curseur reste en mode 'sablier'

Normal, la fenêtre ne traite pas les messages cf Form.ShowDialog.

>- Avant ou sans le while() quand je quitte le programme il y a une
exception
>NullReference. Je pense qu'il s'agit du framework qui n'accède pas
correctement
>au handler du form.
>

cf:





http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/default.aspx

>Donc je cherche quelle méthode est valide pour ce genre de problème ?
>
>cyrille




Merci Paul pour tous ces liens que je vais lire après cette précision :

Je souhaite avoir 2 fenêtres avec chacune son thread d'exécution.
Les 2 fenêtres doivent être accessibles par l'utilisateur, donc pas de
ShowDialog.




Si chaque Thread est dans un ShowDialog, vous pouvez afficher et interagir
avec les 2 boîtes de dialogues.
ShowDialogue ne fait qu'utiliser une pompe à message. Chaque Thread
(graphique) a sa propre pompe à message et il n'y a donc aucune interférence
entre les 2 boites de dialogue, CQFD.
Si vous ne me croyez pas, créez une fenêtre et sur un click bouton qui crée
un thread qui lui même crée un formulaire et l'affiche avec ShowDialogue.
Vous aurez 2 formulaires qui bougent.
Exemple avec 3 threads au total :
private static void toto()
{
Form4 form4 = new Form4();
form4.ShowDialog();
}
private void button1_Click(object sender, System.EventArgs e)
{
System.Threading.Thread thread1 = new System.Threading.Thread(new
System.Threading.ThreadStart(toto));
thread1.Start();
System.Threading.Thread thread2 = new System.Threading.Thread(new
System.Threading.ThreadStart(toto));
thread2.Start();
}


La 1ere fenêtre est un form 'normal' avec des controls, la seconde comporte


un
ocx Shockwave Flash. Elle nécessite un second thread pour que les


animations
Flash ne soient pas stoppées lorsque la 1ere fenêtre exéxute un calcul.





Aucun problème car les 2 Thread sont indépendants, l'un des formulaire
héberge l'OCX tandis que l'autre fait son calcul.

Quand vous aurez bien assimilé la notion de thread, je pense qu'il serait
pour vous avantageux de mettre ce calcul dans un WorkerThread et non dans un
Thread graphique.



Peut être as tu d'autres liens ou d'autres explications plus adaptés à


cette
configuration.




Je pense que les 2 liens précédents sont indispensables pour avoir une
certaine maîtrise des Threads et qu'ils suffisent amplement pour votre
problème.


Merci
Cyrille




--
Paul Bacelar
Avatar
cyrille
In article <eYdHU5c#,
says...
>"cyrille" wrote in message
news:
>In article <OqhGk5Q#,
> says...
>> >"cyrille" wrote in message
>> news:
>> >In article ,
says...
Si chaque Thread est dans un ShowDialog, vous pouvez afficher et interagi r
avec les 2 boîtes de dialogues.
ShowDialogue ne fait qu'utiliser une pompe à message. Chaque Thread
(graphique) a sa propre pompe à message et il n'y a donc aucune interf érence
entre les 2 boites de dialogue, CQFD.
Si vous ne me croyez pas, créez une fenêtre et sur un click bouton qu i crée
un thread qui lui même crée un formulaire et l'affiche avec ShowDialo gue.
Vous aurez 2 formulaires qui bougent.
Exemple avec 3 threads au total :
private static void toto()
{
Form4 form4 = new Form4();
form4.ShowDialog();
}
private void button1_Click(object sender, System.EventArgs e)
{
System.Threading.Thread thread1 = new System.Threading.Thread(new
System.Threading.ThreadStart(toto));
thread1.Start();
System.Threading.Thread thread2 = new System.Threading.Thread(new
System.Threading.ThreadStart(toto));
thread2.Start();
}



Merci beaucoup Paul pour cette solution du ShowDialog(),
ça fonctionne très bien, sauf que ...

Quand je ferme les fenêtres, l'application lève une exception :

Une exception non gérée du type 'System.NullReferenceException' s'est p roduite
dans system.windows.forms.dll

La pile des appels est :
system.windows.forms.dll!
System.Windows.Forms.AxHost.ConnectionPointCookie.Disconnect() + 0x25 octet s
system.windows.forms.dll!
System.Windows.Forms.AxHost.ConnectionPointCookie.Finalize() + 0x1c octets

Et l'IDE affiche le code machine de
System.Windows.Forms.AxHost.ConnectionPointCookie.Disconnect

On dirait donc que l'ocx shockwaveflash n'aime pas cette configuration.
Pourtant dans la form1 je n'ais aucune référence à celui-ci.

Seule la seconde fenêtre, qui est ouverte depuis le nouveau thread avec
ShowDialog(), contient la réf sur l'ocx.

Une idée ?
cyrille
Avatar
Paul Bacelar
>"cyrille" wrote in message


news:
In article <eYdHU5c#,
says...
>"cyrille" wrote in message
news:
>In article <OqhGk5Q#,
> says...
>> >"cyrille" wrote in message
>> news:
>> >In article ,
says...
Si chaque Thread est dans un ShowDialog, vous pouvez afficher et




interagir
avec les 2 boîtes de dialogues.
ShowDialogue ne fait qu'utiliser une pompe à message. Chaque Thread
(graphique) a sa propre pompe à message et il n'y a donc aucune




interférence
entre les 2 boites de dialogue, CQFD.
Si vous ne me croyez pas, créez une fenêtre et sur un click bouton qui




crée
un thread qui lui même crée un formulaire et l'affiche avec ShowDialogue.
Vous aurez 2 formulaires qui bougent.
Exemple avec 3 threads au total :
private static void toto()
{
Form4 form4 = new Form4();
form4.ShowDialog();
}
private void button1_Click(object sender, System.EventArgs e)
{
System.Threading.Thread thread1 = new System.Threading.Thread(new
System.Threading.ThreadStart(toto));
thread1.Start();
System.Threading.Thread thread2 = new System.Threading.Thread(new
System.Threading.ThreadStart(toto));
thread2.Start();
}



Merci beaucoup Paul pour cette solution du ShowDialog(),
ça fonctionne très bien, sauf que ...

Quand je ferme les fenêtres, l'application lève une exception :

Une exception non gérée du type 'System.NullReferenceException' s'est


produite
dans system.windows.forms.dll

La pile des appels est :
system.windows.forms.dll!
System.Windows.Forms.AxHost.ConnectionPointCookie.Disconnect() + 0x25


octets
system.windows.forms.dll!
System.Windows.Forms.AxHost.ConnectionPointCookie.Finalize() + 0x1c octets

Et l'IDE affiche le code machine de
System.Windows.Forms.AxHost.ConnectionPointCookie.Disconnect

On dirait donc que l'ocx shockwaveflash n'aime pas cette configuration.
Pourtant dans la form1 je n'ais aucune référence à celui-ci.

Seule la seconde fenêtre, qui est ouverte depuis le nouveau thread avec
ShowDialog(), contient la réf sur l'ocx.

Une idée ?
cyrille



Sur la fermeture de laquelle des 2 fenêtres ?



Si c'est sur la première (sans shockwaveflash)

J'ai 2 explications.

Votre second thread n'est pas un thread en tache de fond (propriété
IsBackground à mettre à true avant de démarrer le thread)

Vous n'avez vraisemblablement pas lu les articles que je vous ai référencé.

Si vous avez toujours un problème avec le composant, c'est qu'il supporte
assez mal les interruptions violentes de thread et que vous devez concevoir
un mécanisme de demande de terminaison du thread secondaire par le premier
(Control.Invoke est d'une grande utilité pour cela)



Si c'est en fermant la seconde fenêtre, pouvez-vous nous donner plus d'info
ou un code source pour reproduire le problème.

Mais cela ne devrait pas être inhérent au mécanisme mise en place mais au
composant shockwaveflash.


--
Paul Bacelar