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
Vincent Burel
Je ne sais pas si ca va vous aider, mais il faut faire très attention aux
controles windows (fenetre) en multithread.
car certain control (HWND) peuvent appeler leur callback relative
(généralement dans le thread primaire) pour répondre à certains message
pouvant venir d'un autre thread. Evidemment si le thread primaire est en
train d'attendre, on va se retrouver avec un deadlock.

Souvent, il vaut mieux laisser le thread primaire s'occuper des controles
windows, et éviter que d'autre thread envoient des messages directement à
ces controles. il vaut mieux par exemple interroger le thread2 par timer ou
faire un mécanisme de message différé (par PostMessage par exemple).

Si le thread2 crée et controle une fenetre windows à part entière , alors il
faut qu'il soit similaire à votre 'main' section, c'est a dire qu'il doit
contenir une boucle de message juste après la création de la fenetre
principale, et les autres fonctions de ce thread devront etre géré dans la
callback de cette fenetre.

VB

wrote in message
news:
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();
}

[...]
Avatar
Sylvain
wrote on 07/09/2007 17:19:
Bonjour à tous. je vous sollicite pour un problème délicat.

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.



cela devrait être l'inverse; le thread principal pompe les messages
(gère l'UI - Windows est, assez souvent, un système graphique avec
interface utilisateur); le(s) thread(s) secondaire(s) gèrent le
traitement, si besoin il(s) postent des msg standards ou utilisateurs
pour mettre à jour l'UI.

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



?!? peut être à poster sur un forum::special::language::abscond ...

[...]

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



on poste des messages depuis les threads secondaires vers le thread UI,
on poste des notifications (ou accès aux données membres ou autres)
depuis le thread principal vers les threads secondaires.

Sylvain.
Avatar
mickeydisn
On 7 sep, 18:30, "Vincent Burel"
wrote:
Je ne sais pas si ca va vous aider, mais il faut faire très attention a ux
controles windows (fenetre) en multithread.
car certain control (HWND) peuvent appeler leur callback relative
(généralement dans le thread primaire) pour répondre à certains m essage
pouvant venir d'un autre thread. Evidemment si le thread primaire est en
train d'attendre, on va se retrouver avec un deadlock.




Il me semble que c'est vrais pour les forms windows ATL ou MFC mais ce
nais plus le cas pour les winform .net ( vraiment pas sur)

Souvent, il vaut mieux laisser le thread primaire s'occuper des controles
windows, et éviter que d'autre thread envoient des messages directement à
ces controles. il vaut mieux par exemple interroger le thread2 par timer ou
faire un mécanisme de message différé (par PostMessage par exemple).




Tres bonne remarque .. mais cela ne resous aps mon Probleme je
n'arriver toujour pas a faire delegate dans les 2 sens :('


Si le thread2 crée et controle une fenetre windows à part entière , alors il
faut qu'il soit similaire à votre 'main' section, c'est a dire qu'il do it
contenir une boucle de message juste après la création de la fenetre
principale, et les autres fonctions de ce thread devront etre géré da ns la
callback de cette fenetre.




La encore la gestion .net et differante .. la nouvelle couche de
"gestion de class managée" C++/CLI a beaucoup simplifiée le probleme.
Avatar
mickeydisn
On 7 sep, 19:57, Sylvain wrote:
on poste des messages depuis les threads secondaires vers le thread UI,
on poste des notifications (ou accès aux données membres ou autres)
depuis le thread principal vers les threads secondaires.




J'ai noter le fais que j'ai code a l'enver. et que la winform devrais
etre en TH1 et ma boucle en TH2 .. mais si je suis ton resonement..
dans ce que j'ai fais mon interface devrais envoyer des message et ma
boucle des notification .. or c'est le cas inverse .. et c'est bein
l'envoie de message du TH2 -> TH1 qui ne marche pas (si l'utilisation
des delagete en C++/CLI fonctionne bein sur la basse d'envoie de
message . )