Juliane15
Messages postés3Date d'inscriptionjeudi 21 mai 2009StatutMembreDernière intervention23 mai 2009
-
20 mai 2009 à 22:53
cs_Robert33
Messages postés834Date d'inscriptionsamedi 15 novembre 2008StatutMembreDernière intervention14 janvier 2017
-
24 mai 2009 à 19:51
Salut tout le monde
Je développe une application (détecter les routes et dessiner leurs bordures sur l'image.) en c# qui exécute des fonctions lourdes se trouvant toutes dans une seule classe et qui font appel les unes aux autres.
J'ai besoin de rajouter une fonction qui consiste à arrêter l'exécution à un moment donné pour se contenter du résultat préliminaire, ceci doit être fait avec les threads et la méthode invoke.
A présent je ne parviens pas à ce résultat, en appuyant sur la forme en plein exécution celle-ci devient bloquante, merci de me donner une idée comment le faire.
Voici le schéma approximatif :
private
void ButtonExecute_Click(object sender, EventArgs e)<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
{
Thread
t = newThread(newThreadStart(launchInvoke));
cs_Robert33
Messages postés834Date d'inscriptionsamedi 15 novembre 2008StatutMembreDernière intervention14 janvier 201733 22 mai 2009 à 20:27
Bonsoir,
Il n'y a pas beaucoup de solutions,
Soit tu Kill violament le thread
Soit tu positionnes un booleen dans un ojbet global (singleton static) que tu testes dans toutes tes boucles pour savoir si tu continues ou pas.
Juliane15
Messages postés3Date d'inscriptionjeudi 21 mai 2009StatutMembreDernière intervention23 mai 2009 23 mai 2009 à 16:39
Je parviens à résoudre le problème du parallélisme en utilisant backgroundWorker, par contre, il reste le problème du dessin des bordures, parce que dans myclasse.myMethode je fais bForm.pictureBox1.Refresh(); ce qui me signale une erreur « accès à un contrôle par un thread autre que celui qui l’a crée », j’ai du ensuite désactiver la génération de cette exception par Control.CheckForIllegalCrossThreadCalls = false; (ce qui n’est pas recommandé), de ce fait, j’ai obtenu une exécution (normale) mais sans que les bordures ne soient dessinées sur l’image (pictureBox1_Paint n’est jamais appelée).
J’ai pensé également de faire (sur la classemyClass) :
private static void pictureBox1Refresh()
{
bForm.pictureBox1.Refresh(); // bForm : mon formulaire de base
}
private static void myMethode (baseForm bForm)
{
// extraction c.à.d. calcule des points des bordures et les mettre dans
// arrayListPoints
Je ne sais pas si cette solution pourrai être juste, mais ma difficulté actuelle réside sur le passage des paramètres [param] (la création d’un object et d’un PaintEventArgs) merci de m’aider à continuer cette solution ou de me proposer une autre.
cs_Robert33
Messages postés834Date d'inscriptionsamedi 15 novembre 2008StatutMembreDernière intervention14 janvier 201733 24 mai 2009 à 19:51
Bonjour,
Pour régler le probleme de l'exception d'acces au ressource depuis un autre thread tu dois fournir un delegate, mais pas necessairement avec la même signature que l'evenement.
ex pour inserrer un message dans un texte box
Dans ta form définit un delegate simple:
delegate void SetData(string data);
au moment ou tu veux ecrire dans le text box, ajout ce code:
if (textBox2.InvokeRequired)
{
textBox2.Invoke(new SetData(AddMessage), new object[] { "mon message" });
}
else
{
AddMessage ("mon message");
}
puis définis la methode AddMessage
void AddMessage(string message)
{
textBox2.Text += Environment.NewLine + message;
textBox2.Select(textBox2.Text.Length, 1);
textBox2.ScrollToCaret();
}
En fait le delegate permet l'appel à une methode depuis un autre thread, l'execution de la methode est deleguée à l'objet invoké.
La signature du delegate correspond à celle de la methode qui sera appelée, dans ce cas:
delegate voidSetData(string data);
void AddMessage(string message)
L'instanciation du delegate set à associer la mehode qui sera appelée:
new SetData(AddMessage)
Mais pour l'execution il faut passer à la methode les parametres qu'elle attend, dans notre cas un seul parametre de type string.
textBox2.Invoke(new SetData(AddMessage), new object[] { "mon message" });
La methode Invoke etant generique il faut pouvoir passer n'inporte quel type d'objets et comme le nombre peut varié, la seul solution est un tableau d'objet.
Les parametres doivent être passé dans l'odre de leur déclaration.
ex, si la méthode avait attendu 2 parametres:
void AddMessage(string message, bool scroll)
Le delegate aurrait été :
delegate voidSetData(string data, bool scroll);
L'appel aurait été :
textBox2.Invoke(new SetData(AddMessage), new object[] { "mon message" , true});