Cross-Thread Erreur

Signaler
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008
-
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008
-
Bonjour, voila j'suis un debutant en programmation, je suis tomber sur cette source, mais lorsque je lance l'application, Visual Studio m'indique qu'il y a un problème de Cross-Thread, je ne sais pas comment m'y prendre, voila, je voulais savoir si vous aver la soluce ou une explication à me donner, Merci.

Je précise que CancelForm() est un simple formulaire avec un boutton (cancel).

using

System;
using

System.Diagnostics;
using

System.Windows.Forms;
using

System.Threading;
using

System.Drawing;
namespace

Article4{

///<summary>

/// Class permettant l'éxécution d'arj

///</summary>

public
class
Arj :
MainForm{

private
CancelForm winStop;

private
Process arjProcess;

public
int UnArj(
string arjFileName,
string outputPath){

int exitCode ;

// création de la fenêtre d'arrêtwinStop =

new
CancelForm();

// instanciation du thread pour la lecture de l'affichage du processus

Thread readInfo =
new
Thread(
new
ThreadStart(
this.readOutput));

// définition du processus externe (arj)

ProcessStartInfo processInfo =
new
ProcessStartInfo(
@"c:\Windows\System32\cmd.exe");processInfo.Arguments =

"e -y " + arjFileName +
" " + outputPath;
// on déroute la sortie standardprocessInfo.UseShellExecute false;processInfo.CreateNoWindow

true;processInfo.RedirectStandardOutput =

true;

arjProcess =

new
Process();arjProcess.StartInfo = processInfo;

// on utilise l'évènement pour savoir quand le processus est terminé.arjProcess.EnableRaisingEvents =

true;arjProcess.Exited +=

new
EventHandler(arjEnded);

// démarrage du processus et du threadarjProcess.Start();

 // on démarre le thread de lecture
readInfo.Start();

 //on affiche la fenêtre de dialogue
winStop.ShowDialog();

// on vérifie si le processus est fini.

// Si ce n'est pas le cas, l'utilisateur a appuyé sur stop

// et il faut fermer le processus

if ( ! arjProcess.HasExited ){

arjProcess.Kill();

arjProcess.WaitForExit();

}

// après le close, les infos sur le processus ne seront plus

// disponible. La mémoire allouée pour conserver ces infos

// est rendue disponible.exitCode = arjProcess.ExitCode;

arjProcess.Close();

return exitCode;}

private
void arjEnded(
object sender, System.
EventArgs e){

winStop.Close();

}

private
void readOutput(){

char[] buffer =
new
char[1];

char car1 =
' ';

char car2 =
' ';

char car =
'%';

// lecture de la sortie tant que le processus n'est pas fini

while (! arjProcess.HasExited){

arjProcess.StandardOutput.Read(buffer,0,1);

// Si le caractère lu est un % on réaffiche le pourcentage

if (buffer[0] == car){

winStop.lblInfo.Text =

Convert.ToString(car1)+
Convert.ToString(car2) +
"%";}

// on enregistre les deux derniers caractères lu avant une nouvelle lecture.car1 = car2;

car2 = buffer[0];

}

}

}

}

13 réponses

Messages postés
128
Date d'inscription
mardi 18 décembre 2007
Statut
Membre
Dernière intervention
2 août 2009
3
Salut, est-ce que tu me donner le lien de la source s'il te plait?
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

Messages postés
128
Date d'inscription
mardi 18 décembre 2007
Statut
Membre
Dernière intervention
2 août 2009
3
Oui c'est un appel inter-thread. Un thread ne peut pas modifier un autre thread.
Ce qu'il faut faire, c'est que le thread2 demande au thread1 de se modifier.

Tu peux regarder le delegate, c'est le seul moyen que je connaisse pour faire des appels inter-thread.
A cette adresse, MorpionMx à fait un dossier sur les opération cross-thread. C'est très bien expliqué.

http://www.csharpfr.com/tutoriaux/CSHARP-OPERATIONS-CROSS-THREADS-UTILISATION-DELEGATIONS-SYNCHRONES-ASYNCHRONES_174.aspx

Si tu as des soucis, dis-le!

LP
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

Merci pour le lien, je vais voir si j'arrive sinon je reviens.
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

je demande de l'aide, car je n'arrive vraiment pas (c'est pas de faute de vouloir essayer), si quelqu'un à la solution, pour y remedier sa serait sympa, Merci.
Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
9
Grosso modo le principe est le suivant :

Tu dois avoir une erreur lorsque tu essaye de modifier un composant graphie, par exemple sur une ligne ressemblant a celle la :

public void UneMethode(object unParam)
{
    unComposant.Text = "toto";// L'erreur est déclenché ici
}

L'erreur que tu as signifie que tu tente de modifier un controle graphique depuis un autre thread que le thread qui a créé le control. La solution est donc de modifier l'appel à la méthode modifiant le control pour qu'elle ne soit plus faite par un thread exterieur, mais pas le thread "père" du control.

Dans ce cas, la solution ressemble à ça (en gras ce qu'il faut ajouter) :

public delegate void UneMethodeDelegate(object unParam); // Délégué utilisé pour rappeler la méthode

public void UneMethode(object unParam)

{
    if(unComposant.InvokeRequired)
    {
        // InvokeRequired = true : le thread courant n'est pas le bon et qu'il faut invoker la methode depuis un autre thread
       UneMethodeDelegate d = new UneMethodeDelegate(UneMethode); // délégué vers notre méthode
       unComposant.Invoke(d, unParam); // C'est le composant qui ré-invoke lui même la méthode, depuis son "propre thread"
    }
    else
    {
        // On est sur le thread courant du control, on peut le modifier

        unComposant.Text = "toto"; // L'erreur est déclenché ici
    }

}

Si tu ne comprends toujours pas comment corriger ton problème, donnes nous le bout de code où est levée l'exception...

<hr size ="2" width="100%" />
Working as designed
www.nikoui.fr
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

Voila c'est ici que sa bug (en mode pas à pas --> "Cannot access a disposed object. Object name: 'CancelForm'.")



winStop.Show();
Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
9
Dans ce cas ce n'est pas un problème de cross thread call comme indiqué dans ton premier message (et tu peux donc oublier les réponses ci-dessus).

Visiblement tu essaye d'afficher une Form (de quel type est winStop ?) alors que tu as du faire un "Close" sur cette Form précédement.

Si c'est bien ça, et que tu cherches a "Fermer/Rouvrir" une fenêtre, soit il faut la recréer à chaque fois, soit il faut remplacer l'éventuel "Close" par un "Hide" (et tu pourras ensuite refaire "Show" dessus).

N'hésites pas à mettre un peu plus de code, c'est plus facile pour comprendre ce qu'il se passe ;)

<hr size="2" width="100%" />
Working as designed
www.nikoui.fr
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

Si si, c'est bien un probleme de cross-thread le code ce trouve içi  (sa serait sympa que tu l'essaye toi même):

http://jab.developpez.com/tutoriels/dotnet/process/synchrone/
Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
9
Le message "Cannot access a disposed objecté
" n'est pas lié à un problème de cross thread call. Par contre, il est possible que tu n'est le problème de cross thread call qu'en debugant pas a pas (ou l'inverse, que tu ne l'est pas en debugant pas a pas, mais en execution normale).

Tu as donc à mon avis les 2 problèmes à corriger, et pas mal de pistes données plus haut...

(je ne peux pas regarder plus en détail tout le code maintenant)

<hr size="2" width="100%" />
Working as designed
www.nikoui.fr
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

Le code ne viens pas de moi, j'ai juste l'envie de savoir comment y remedier au probleme causer ( y' a une solution mais c'est deconseillé : CheckForIllegalCrossThreadCalls = false;)
Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
9
La solution t'a déjà été expliqué deux fois (par le tutorial de MorpionMx et par moi même), qu'est ce que tu veux de plus?

As tu essayé de comprendre ce qu'il se passait et quelle était la solution proposée ? Où bloques tu exactement ?

<hr size="2" width="100%" />
Working as designed
www.nikoui.fr
Messages postés
16
Date d'inscription
dimanche 2 juillet 2006
Statut
Membre
Dernière intervention
15 juillet 2008

Merci pour l'aide que vous m'avez apportez, mais je n'ai toujours pas resolu le problème (je ne sais pas vraiment qu'est ce qu'il me bloque), donc si quelqu'un peut m'apporter la solution (Je débute en prog), sa me ferra qu'avancer pour mes futurs progs.
Merci.