Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

System::Threading delagate Invoke bloqué

4 réponses
Avatar
mickeydisn
Bonjour =E0 tous. je vous sollicite pour un probl=E8me d=E9licat.

R=E9sum=E9e :

Mon application est composer de 2 Thread:
- Le premier est une boucle while(true) { Th1::Action() } qui
ex=E9cute un ensemble de fonction ...
- Le second est une interface graphique winform qui doit me
permettre d'afficher ce qui ce passe dans la boucle de mon Th1.

Dans mon main cela ce passe ainci :
- Creation du Th2 dans un Singloton A:

A::Thread2_Start()
{
this->CreateControl();
_threadform =3D gcnew System::Threading::Thread(gcnew
System::Threading::ThreadStart(this, &A::ThrFunc2));
_threadform->Name =3D "Thread2";
_threadform->Start();
}

- Puis Ex=E9cution de la boucle While...


Afin de modifier l'affichage de la form depuis la boucle .. je fais
appel a des delegate que j'ai d=E9clar=E9s et instansi=E9s dans le singloton
A=2E

ref class A : public System::Windows::Forms::Control
{
....

delegate void Delegate_add_err(String ^s);
Delegate_add_err ^D_add_err;
void MD_add_err(String ^s)
{
this->_form1->text_err->Text +=3D s + Environment::NewLine;
}


void ThrFunc2()
{
...
this->D_add_err =3D gcnew Delegate_add_err(this, &A::MD_add_err);
=2E..
}

}


Ensuite dans ma boucle j'utilise :
A::get_inst()->Invoke(A::get_inst()->D_add_err, "...");

Jusqu'ici pas de PB tout fonction comme je le souhaite .. Le pb
arrive ..

Je veut a partir de ma form interferer avec ma boucle ( changer des
valeur ... ) en gros executer une fonction sur le TH1.

j'ai donc cree des delegates dans mon singloton A et les instancier
dans avant de cree le theard 2

A::Thread2_Start()
{
this->D_th1_fonction =3D gcnew Delegate_th1_fonction(this,
&A::MD_th1_fonction);
....
_threadform->Start();
}


Le pb lors ce que je fais un Invoke depuis le Thread2 de ce delagate..
il reste bloqu=E9 sur le Invoke ..

Comment peux ton faire pour r=E9soudre ce PB .. comment faire une
communication avec des delegate dans les 2 sens. surtout Th2 > Th1 .



Ps : Je m'excuse de ne pas =EAtre plus claire sur le code .. mais je
suis dans un programme de plus de 10000 ligne .. j'esp=E8re avec d=E9gager
le plus clairement possible le PB.


Merci a ceux qui ce pencherons sur le Probleme.

--
MickeyDisn

4 réponses

Avatar
Gilles TOURREAU
Le Fri, 07 Sep 2007 17:20:57 +0200, a écrit:

Bonjour à tous. je vous sollicite pour un problème délicat.

Résumée :

Mon application est composer de 2 Thread:
- Le premier est une boucle while(true) { Th1::Action() } qui
exécute un ensemble de fonction ...
- Le second est une interface graphique winform qui doit me
permettre d'afficher ce qui ce passe dans la boucle de mon Th1.

Dans mon main cela ce passe ainci :
- Creation du Th2 dans un Singloton A:

A::Thread2_Start()
{
this->CreateControl();
_threadform = gcnew System::Threading::Thread(gcnew
System::Threading::ThreadStart(this, &A::ThrFunc2));
_threadform->Name = "Thread2";
_threadform->Start();
}

- Puis Exécution de la boucle While...


Afin de modifier l'affichage de la form depuis la boucle .. je fais
appel a des delegate que j'ai déclarés et instansiés dans le singloton
A.

ref class A : public System::Windows::Forms::Control
{
....

delegate void Delegate_add_err(String ^s);
Delegate_add_err ^D_add_err;
void MD_add_err(String ^s)
{
this->_form1->text_err->Text += s + Environment::NewLine;
}


void ThrFunc2()
{
...
this->D_add_err = gcnew Delegate_add_err(this, &A::MD_add_err);
...
}

}


Ensuite dans ma boucle j'utilise :
A::get_inst()->Invoke(A::get_inst()->D_add_err, "...");

Jusqu'ici pas de PB tout fonction comme je le souhaite .. Le pb
arrive ..

Je veut a partir de ma form interferer avec ma boucle ( changer des
valeur ... ) en gros executer une fonction sur le TH1.

j'ai donc cree des delegates dans mon singloton A et les instancier
dans avant de cree le theard 2

A::Thread2_Start()
{
this->D_th1_fonction = gcnew Delegate_th1_fonction(this,
&A::MD_th1_fonction);
....
_threadform->Start();
}


Le pb lors ce que je fais un Invoke depuis le Thread2 de ce delagate..
il reste bloqué sur le Invoke ..

Comment peux ton faire pour résoudre ce PB .. comment faire une
communication avec des delegate dans les 2 sens. surtout Th2 > Th1 .



Ps : Je m'excuse de ne pas être plus claire sur le code .. mais je
suis dans un programme de plus de 10000 ligne .. j'espère avec dégager
le plus clairement possible le PB.


Merci a ceux qui ce pencherons sur le Probleme.

--
MickeyDisn




Vous vous êtes trompé de forum, ici c'est le forum pour C# et non C++...

En tout cas pour votre problème sachez que :
- La méthode Invoke présente dans Control sert uniquement à executer du
code dans le Thread d'affichage et ainsi pouvoir modifier des propriétés
(Font, Color,...etc) des contrôles... Ce procédé est uniquement spécifique
à l'affichage sous Windows...
- Pour communiquer entre Thread il suffit d'avoir une variable commune
entre les threads et utiliser les systèmes de moniteur, mutex,...etc pour
assurer la bonne intégrité de cette variable. En c# on a le mot clé "lock"
qui permet de faire très simplement des zones à exclusion mutuelle (mutex).

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
mickeydisn
On 7 sep, 18:14, "Gilles TOURREAU" wrote:
Vous vous êtes trompé de forum, ici c'est le forum pour C# et non C++ ...




Je sais mais je n'est pas trouver le forum C++/CLI et le C# utilise
les meme fonction de .net

En tout cas pour votre problème sachez que :
- La méthode Invoke présente dans Control sert uniquement à execute r du
code dans le Thread d'affichage et ainsi pouvoir modifier des propriét és
(Font, Color,...etc) des contrôles... Ce procédé est uniquement sp écifique
à l'affichage sous Windows...



J'avais pas comprie ca, et c'est une tres bonne information .. avais
vous un lien qui peut m'en dir plus .

- Pour communiquer entre Thread il suffit d'avoir une variable commune
entre les threads et utiliser les systèmes de moniteur, mutex,...etc po ur
assurer la bonne intégrité de cette variable. En c# on a le mot clé "lock"
qui permet de faire très simplement des zones à exclusion mutuelle (m utex).

Cordialement





Je voie tout a fais le principe et vais tester ca rapidement ..

C'est forme dommage quand meme que les fonctions Invoke ne marche pas
sur des objet qui ne sont pas graphique .. on ne peut pas cree d'objet
deriver qui permetrais d'utiliser cette methode avec plus de
liberter ?
Avatar
Gilles TOURREAU
Le Fri, 07 Sep 2007 21:35:47 +0200, a écrit:

On 7 sep, 18:14, "Gilles TOURREAU" wrote:
Vous vous êtes trompé de forum, ici c'est le forum pour C# et non C++...




Je sais mais je n'est pas trouver le forum C++/CLI et le C# utilise
les meme fonction de .net

En tout cas pour votre problème sachez que :
- La méthode Invoke présente dans Control sert uniquement à executer du
code dans le Thread d'affichage et ainsi pouvoir modifier des propriétés
(Font, Color,...etc) des contrôles... Ce procédé est uniquement
spécifique
à l'affichage sous Windows...



J'avais pas comprie ca, et c'est une tres bonne information .. avais
vous un lien qui peut m'en dir plus .

- Pour communiquer entre Thread il suffit d'avoir une variable commune
entre les threads et utiliser les systèmes de moniteur, mutex,...etc
pour
assurer la bonne intégrité de cette variable. En c# on a le mot clé
"lock"
qui permet de faire très simplement des zones à exclusion mutuelle
(mutex).

Cordialement





Je voie tout a fais le principe et vais tester ca rapidement ..

C'est forme dommage quand meme que les fonctions Invoke ne marche pas
sur des objet qui ne sont pas graphique .. on ne peut pas cree d'objet
deriver qui permetrais d'utiliser cette methode avec plus de
liberter ?




Non,
Je ne vois pas pourquoi vous souhaitez utiliser des méthodes "style
Invoke" ?

Que votre code s'execute dans un Thread ou dans un autre le résultat est
le même si les variables partagées sont bien protégée via des Mutex...

Grosso modo :

Le Thread d'affichage de Windows, passe son temps à dessiner à l'écran et
lire des informations sur les contrôles (Text, Font, Color,...etc).
Lorsque vous executez du code style :

TraiterDesDonnées();
MonControl.Font = NouvelleFont();

Vous le faites (forcement) dans le Thread d'affichage, c'est à dire qu'a
ce moment le Thread d'affichage ne dessine plus et execute votre code...
ensuite vu que le Thread d'affichage n'a pas de code a executer, il
continue a dessiner...

Microsoft a mis en oeuvre ce mécanisme de Control.Invoke() car si vous
executez la ligne suivante dans un autre Thread :
MonControl.Font = NouvelleFont();
Cela va poser des problème au Thread d'affichage qui peut-être en train de
lire des informations sur la Font du contrôle qui est en train de
dessiner...

Tandis que si vous executez le code précédent dans le Thread d'affichage,
cela ne posera pas de problème car aucun dessin n'est en cours...

Ce que je vous raconte est très simplifié... En fait tout ces mécanismes
sont mis en oeuvre via de système de message de Windows... Mais c'est le
principe qu'il faut garder à l'esprit... Plus techniquement le
Control.Invoke ajoute un message dans la liste des messages à traiter du
Thread d'affichage.

Personnellement, je trouve le système de Control.Invoke() pas très souple
pour une programmation multi-thread (obligé de créer un Delegate + une
méthode pour affecter une propriété d'un contrôle), mais on n'a pas le
choix... L'idéal étant d'affecter directement une propriété d'un contrôle
depuis n'importe quel Thread...

Expliquez ce que vous souhaitez faire, sinon si vous tenez absolument a
vos méthodes Invoke(), il suffit de créer une file de message "à la
Windows"...
Si vous souhaitez une communication entre Thread, un jeu de variable-mutex
suffit largement... Simple à mettre en oeuvre, à débugguer, et très peu de
ressources utilisées...

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
mickeydisn
Merci beaucoup de votre reponce et de ca calité. je pence poseder
maintenent tout les informations utilie pour continuer mes recherche
et trouver la bonne solution a mon probleme ..