1

In this case I launch a application and read its output value using StandardOutput and StandardError and write it to a file.once the process is launched two different threads are launched which reads the output from the stream and set certain strings which are used to write the same into outout file by main thread.Sometimes(Extremely rare scenario) the process.waitforexit() does not return and wait indefinitely.I have gone through similar questions at here but cant relate if I have the same issue.

Below is my code-

private Thread outThread = null;
        private Thread errThread = null;
        private string outputText = "";
        private string errorText = "";
        private StreamReader outStream = null;
        private StreamReader errStream = null;

protected void ReadError()
        {
            if (errStream != null) {
                errorText = errStream.ReadToEnd();
            }
        }

        protected void ReadOutput()
        {
            if (outStream != null) {
                outputText = outStream.ReadToEnd();
            }
        }

public int launchProcess(string process, string arguments, StringDictionary env, int timeout, string logfile)
        {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.Arguments = arguments;
            psi.FileName = process;
            //psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = false;
            if (env != null)
            {
                psi.EnvironmentVariables.Clear();
                foreach (string key in env.Keys)
                {
                    psi.EnvironmentVariables.Add(key, env[key]);
                }
            }

            int time = (timeout == -1) ? int.MaxValue : timeout;

            if (logfile != null && time != 0)
            {
                psi.RedirectStandardOutput = true;
                psi.RedirectStandardError = true;
                psi.RedirectStandardInput = true;
            }

            try
            {
                Process p = Process.Start(psi);
                if (time != 0)
                {
                    if (logfile != null)
                    {
                        outStream = p.StandardOutput;
                        errStream = p.StandardError;
                        outThread = new Thread(new ThreadStart(ReadOutput));
                        errThread = new Thread(new ThreadStart(ReadError));
                        outThread.Start();
                        errThread.Start();
                    }

                    p.WaitForExit(time);

                    if (logfile != null) try
                    {
                        outThread.Join();
                        errThread.Join();
                        File.AppendAllText(logfile,
                            String.Format("Running '{0}' with arguments '{1}'\nStandard Output:\n", process, arguments),
                            Encoding.UTF8);
                        File.AppendAllText(logfile, outputText, Encoding.UTF8);
                        File.AppendAllText(logfile, "\n\nStandard Error:\n", Encoding.UTF8);
                        File.AppendAllText(logfile, errorText, Encoding.UTF8);
                    }catch (Exception e){
                        debugMessage("Error occurred while writing standard output to log: " + e.Message);
                    }

                    if (!p.HasExited)
                    {
                        throw new ProcessTimedOutException(psi.FileName);
                    }
                    return p.ExitCode;
                }
                return 0;
            }
            catch (Exception e)
            {
                debugMessage("Unable to launch process " + process + ". " + e.Message);
                return -1;
            }
        }

Please note that in error case the process returns only after I manually kill the process,so I guess this is some deadlock issue. Can anyone help me figuring out the issue here?

Somesh Dhal
  • 336
  • 2
  • 15
  • I am unsure of why you are using threads to read the output, but if `WaitForExit()` is called before `StandardOutput.ReadToEnd()`, it will most likely cause a deadlock – Camilo Terevinto Oct 18 '17 at 12:08
  • The use of threads is not completely clear to me as its legacy code.Can you please tell me in which scenario this might cause deadlock here? – Somesh Dhal Oct 18 '17 at 12:09
  • AFAIK, in any scenario that the process writes to the StandardOutput or StandardInput – Camilo Terevinto Oct 18 '17 at 12:11
  • If that's the case it should happen everytime as I am sure that the process returns some output.But we have seen this only once. – Somesh Dhal Oct 18 '17 at 12:12
  • https://social.msdn.microsoft.com/Forums/vstudio/en-US/22b09f7e-a1b9-4c1d-88b0-f18ffa52cde0/process-hangs?forum=msbuild here the need for multiple threads is explained – Somesh Dhal Oct 18 '17 at 12:21
  • It avoids the traditional deadlock with the threads. But the process just won't quit voluntarily. That happens, maybe you need to send it something. – Hans Passant Oct 18 '17 at 14:36
  • The child process should quit once it returns the output here.I do know if I manually need to kill the process.If so,thread.join() should be present before the waitforexit() to ensure that we have all the data from both streams.Please correct me if I am wrong here. – Somesh Dhal Oct 18 '17 at 16:06

0 Answers0