[C#] changer texte label avec conflit de thread

changer texte label avec conflit de thread [C#] - C#/.NET managed - Programmation

Marsh Posté le 20-05-2009 à 11:59:10    

Salut,
 
J'ai un petit problème au niveau du changement de texte d'un label.
Je m'explique:
J'ai une WinForm qui comporte un Label et utilise une DLL en statique.
L'idée est à chaque clique d'horloge,appeler la fonction Update:
_Appeler la fonction getTemperature() (de la DLL) qui retourne un int,
_Convertir en string cette valeur et la mettre dans un Label de la Winform.
Le problème est qu'au premier clic d'horloge, Visual m'indique que mon application n'est pas ThreadSafe:
Voici le bout de code incriminé:
dans la classe formControl
public void Update()
{
string temp;
m_temperature = getTemperature();
temp = m_temperature.ToString();
this.temperatureValue.Text = temp;
}
L'erreur produite:
Opération inter-threads non valide : le contrôle 'temperatureValue' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé.
 
Je n'ai pas compris en quoi j'ai fais un conflit de threads. J'ai par ailleurs utilisé le lien de visual pour faire du multithreading de manière viable, mais je n'arrive pas a adapter le programme d'exemple pour un Label (il est pour une textBox), ce qui peut s'expliquer par mes faiblesses en ce qui concerne les delegate et Invoke.
 


---------------
"Il faut avoir bien du jugement pour sentir que nous n'en avons point."  
Reply

Marsh Posté le 20-05-2009 à 11:59:10   

Reply

Marsh Posté le 21-05-2009 à 08:27:08    

Tu fais comment pour avoir les "clics d'horloge" ?
Apparemment t'as fait un truc à la mano avec un thread.

 

Tu peux pas utiliser le composant timer ? (ça se trouve dans la toolbox de VS).

 


Si vraiment c'est pas possible alors il faut que tu fasse un Form.Invoke :

 

MyEvent(...)
{
   Form.Invoke(new MethodInvoker(delegate  { Update(); } ));
}

 

Ca permet d'appeler la méthode Update avec le thread de l'UI. En effet, tu n'as pas le droit de modifier l'UI avec n'importe quel thread ;)


Message édité par Ant1_ le 21-05-2009 à 08:40:10
Reply

Marsh Posté le 21-05-2009 à 19:23:19    

Merci de ta réponse,
J'utilise un timer de Vs, c'était imagé. Pourrait tu m'expliquer ce que
 
Form.Invoke(new MethodInvoker(delegate  { Update(); } ));
 
va faire? J'ai assez de mal à piger le Invoke.

Reply

Marsh Posté le 22-05-2009 à 10:32:59    

En fait je n'utilise pas de thread d'horloge, c'est qui m'étonne que cela produise un conflit de thread!

Reply

Marsh Posté le 25-05-2009 à 16:41:45    

Quand est appelée ta méthode "Update()" ?

Reply

Marsh Posté le 26-05-2009 à 14:43:47    

à chaque coup d'horloge:
 
        public void Timer_Tick(object sender, EventArgs eArgs)
        {
            if (sender == this.timer)
            {
                Console.WriteLine("Timer_Tick" );
                this.Update();
               
            }
 
        }

Reply

Marsh Posté le 26-05-2009 à 14:44:42    

sachant que la fonction update se trouve dans formControl qui possède une instance de Timer.

Reply

Marsh Posté le 26-05-2009 à 15:06:26    

Alors, d'abord, je t'invite à lire cette page :
http://msdn.microsoft.com/en-us/li [...] timer.aspx
 
Et notamment ce passage :

Citation :


The method does not execute on the thread that created the timer; it executes on a ThreadPool thread supplied by the system.  


 
Ce qui veut dire que ta fonction Update() est exécutée dans un thread différent. C'est donc ce thread qui accéde au thread principal qui contient ton interface et ses contrôles, et ça, comme le dit Ant1_, c'est interdit, tu dois utiliser BeginInvoke(), qui aura pour effet de placer l'opération de mise à jour de ton controle dans une file d'attente.
 
Plus d'infos ici : http://www.codeproject.com/KB/cs/begininvoke.aspx


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-05-2009 à 16:27:09    

Merci infiniment!

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed