The main form in my application launches a new thread, and then opens another form, which serves as a progress window. The thread pipes some data between 2 console applications, and information from the StandardError is sent to the progress window. I use the DataReceivedEventHandler to read the standarderror asynchronously.
If I let everything run its course, it works perfectly fine, but a problem arises when a user presses the "cancel" button on my form. What happens, is the ErrorDataReceived functions keep firing even after I stop the processes! Sometimes the cancel will work successfully, but sometimes I get a deadlock condition (I think that's the right word).
Here are some snippets of my code so you can see whats happening. It gets stuck waiting on "p2.WaitForExit();" and "Invoke(new updateProgressDelegate(this.updateProgress), e.Data);" (visual studio puts a green arrow by those lines, and says they will be the next to execute)
// 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);
}