C # issue with standard error redirection

The main form in my application starts a new thread and then opens another form, which serves as a progress window. A thread transfers some data between two console applications, and information from StandardError is sent to the execution window. I am using DataReceivedEventHandler to read standarderror asynchronously.

If I let it all work, it works fine, but the problem occurs when the user clicks the cancel button in my form. It happens that the ErrorDataReceived functions continue to fire even after the processes terminate! Sometimes the cancellation will work successfully, but sometimes I get a deadlock condition (I think the right word).

Here are some snippets of my code so you can see what is happening. He was stuck waiting for "p2.WaitForExit ();" and "Invoke (new updateProgressDelegate (this.updateProgress), e.Data); (visual studio puts a green arrow with these lines and says that they will be next for execution)

// 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);
        }
+3
source share
1 answer

two things

In "p2_ErrorDataReceived", you call Invoke (). This may cause your deadlock. You can change this to BeginInvoke ().

Process.WaitForExit() , Kill() WaitForExit, , true, , , :

 p2.Kill();
 if(p2.WaitForExit(waitTime)) //waitTime is the number of milliseconds to wait
 {p2.WaitForExit();}  //waits indefinitely

 //likewise for p

http://msdn.microsoft.com/en-us/library/ty0d8k56.aspx

+1

Source: https://habr.com/ru/post/1722936/


All Articles