Equivalent à Control.Invoke?

leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 - 10 oct. 2006 à 13:47
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 - 11 oct. 2006 à 09:24
Existe-t-il un équivalent à la méthode control.invoke qui aie la meme fonctionnalité, mais lorsque l'on ne dispose pas d'un controle? c'est plus une curiosité qu'un réel problème, mais si on à une classe simple, ou un component, ou nimporte quoi de ce style et que l'on a besoin d'utiliser ce style de procédés, on est obligé de feinter avec un controle temporaire....bon je vous l'accorde, ca arrive pas franchement souvent et à part pour des opérations d'IHM l'interet est un peu limité (auquel cas on dispose de controls)....enfin si quelqu'un possède quand même une réponse.... ;)

8 réponses

cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
10 oct. 2006 à 14:16
Salut,
Si je ne me trompe pas, le cross threading n'arrive que lorsqu'on manipule des objects qui ont un handle. Les objects qui ont un handle sont les objects qui disposents d'une interface graphique (dérivé de la class Control) et ils possèdent donc à ce niveau les méthodes Invoke et BeginInvoke (comme par exemple un UserControl).
Les autres objects n'ayant pas de handle, ils n'ont donc pas besoin de telles méthodes...

VC# forever
0
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
10 oct. 2006 à 14:52
je te donne un exemple (celui qui m'a fait me poser la question).
tu es sur un projet......disons tres gros...
un objet pris dans le ThreadPool (réception de données sur le port com) lève un event et beaucoup (beaucoup) plus loin apres plein d'appels, un composant utilise un System.windows.Forms.Timer et lance ce timer. vu que tu es embarqué dans le ThreadPool, le timer se lance, mais le thread meurt et la méthode qui doit être executée au tick ne se lance jamais (logique).
Hors, le timer peut se lancer dans d'autres contextes pour effectuer ce meme traitement, et dans ce cas on reste dans le Thread principal. bref, soit il faut tout réarchitecterer avec un system.Threading.Timer (un peu casse pied dans le contexte, long, et pas forcément voulu, probable besoin d'instaurer des mutex et compagnie), soit (solution adoptée pour linstant), on crée un control dans le contexte du Thread principal et on fait le invoke pour gagner....2 ou 3h a se casser la tete avec le System.Threading.Timer....
ok, cest tordu (ca l'a été tout autant a débugger ^^)
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
10 oct. 2006 à 22:00
Ton exemple est assez complexe et je doit t'avouer ne pas arriver à visualiser la chose...
Si t'arrives à poster un petit morceau de code, ça pourrait éventuellement aider.

C# forever
-[blogs.developpeur.org/bidou/ Blog]-
0
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
10 oct. 2006 à 22:49
ClassQuiEcouteLePortSerie
{

void SerialDataReceived (object sender, SerialDataReceivedEventArgs e)
{
//ici on est dans le ThreadPool
Class1.MethodQuelconque();
}

}



classQuiNestPasUnControl
{

void EventQuelconque(object sender, EventArgs e)
{
MaMethod();
}

public void MethodQuelconque()
{
MaMethod();
}

void MaMethod()
{
//timer sytem.windows.form
MyTimer.Enabled = true;
}

}



Lorsque MaMethod est appelée par la réception sur le port série, on est dans le ThreadPool, le timer est jamais lancé.
Lorque MaMethod est appelée par la réception de l'autre event, on est pas dans le ThreadPool.
En framework normal je ne suis pas sur du résultat a 100% mais je pense que le timer est correctement géré, mais en compact framework, le timer ne se lance jamais car le Thread meurt...comment faire pour que l'execution lors de la réception dans le port série soit passée séquentiellement au niveau de classe 1 sans :
1 - utiliser un System.Threading.Timer
2 - Utiliser des lock/Mutex/Semaphores (parce que présenté comme ca cest simple mais en réalité ca l'est pas tant que ca)


La solution pour l'instant ca a été un truc du style

classQuiNestPasUnControl
{

private Control m_Control;

private delegate void MyDelegate();

public classQuiNestPasUnControl()
{
m_Control = new Control();
}

void EventQuelconque(object sender, EventArgs e)
{
MaMethod();
}

public void MethodQuelconque()
{
MyDelegate d = new MyDelegate(MethodQuelconque);
m_Control.Invoke(d);
}

void MaMethod()
{
//timer sytem.windows.form
MyTimer.Enabled = true;
}

}



Evidemment ca fonctionne, mais bon conceptuellement, avouons bien que cest pas terrible :(
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
10 oct. 2006 à 22:51
erreur de frappe au dessus :

public void MethodQuelconque()
{
MyDelegate d = new MyDelegate(MaMethod);
m_Control.Invoke(d);
}
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
10 oct. 2006 à 23:49
Fallait préciser que c'était pour le compact framework... Je l'ai jamais utilisé, je sais à peine ce que c'est
Je pense que sous le framework "normal" ça marche, je vais quand même essayer de faire un teste demain si j'ai le temps...

-Blog-
0
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
10 oct. 2006 à 23:57
de ce que j'en sais, la gestion du thread pool est légèrement différente entre compact framework et framework normal.
par exemple, si a la réception dans le port série de données on fait afficher une info dans l'ihm, on plante (pb de cross threading, en faisant du invoke, ca marche nickel), par contre la meme chose sous xp ne plante pas....j'imagine que pour le timer le probleme doit etre le meme. sous framework normal le timer doit etre correctement géré
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
11 oct. 2006 à 09:24
Non ça ne marche pas non plus avec le framework standard (sauf erreur c'était le cas dans la version 1, mais maintenant une exception ce produit (Framework 2))

-Blog-
0
Rejoignez-nous