La principale forme dans mon application lance un nouveau fil, et ouvre alors une autre forme, qui sert de fenêtre de progression. Le thread achemine des données entre deux applications de console et les informations de l'erreur StandardError sont envoyées à la fenêtre de progression. J'utilise DataReceivedEventHandler pour lire l'erreur standard de manière asynchrone.C# problème avec redirection erreur standard
Si je laisse tout son cours, il fonctionne parfaitement bien, mais un problème se pose lorsqu'un utilisateur appuie sur le bouton « annuler » sur mon formulaire. Que se passe-t-il, les fonctions ErrorDataReceived continuer à tirer même après que j'arrête les processus! Parfois, l'annulation fonctionnera avec succès, mais parfois je reçois une condition de blocage (je pense que c'est le bon mot).
Voici quelques extraits de mon code afin que vous puissiez voir ce qui se passe. Il se bloque en attente sur "p2.WaitForExit();" et "Invoke (new updateProgressDelegate (this.updateProgress), e.Data);" (studio visuel met une flèche verte par ces lignes, et dit qu'ils seront le prochain à exécuter)
// start 2 processes (p & p2) and pipe data from one to the other
// this runs in thread t
p.Start();
p2.Start();
byte[] buf = new byte[BUFSIZE];
int read = 0;
p2.ErrorDataReceived += new DataReceivedEventHandler(p2_ErrorDataReceived);
p2.BeginErrorReadLine();
try
{
read = p.StandardOutput.BaseStream.Read(buf, 0, BUFSIZE);
while (read > 0 && read <= BUFSIZE)
{
if (canceled==false)
p2.StandardInput.BaseStream.Write(buf, 0, read);
if (canceled==false)
read = p.StandardOutput.BaseStream.Read(buf, 0, BUFSIZE);
else
{
return;
}
}
}
// this function is called when a user presses the "cancel" button on a form.
private void cancel_encode()
{
if (p2 != null)
{
if (p2.HasExited == false)
p2.Kill();
if (p2.HasExited == false)
p2.WaitForExit();
}
if (p != null)
{
if (p.HasExited == false)
p.Kill();
if (p.HasExited == false)
p.WaitForExit();
}
if (t.IsAlive)
{
if (!t.Join(2000))
t.Abort();
}
}
// this function sends the error data to my progress window
void p2_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && canceled == false)
Invoke(new updateProgressDelegate(this.updateProgress), e.Data);
}
En utilisant BeginInvoke() semble avoir fixé! Merci. – Zarxrax