Process.waitforexit()在重定向进程输出时无限期挂起 [英] Process.waitforexit() hangs for indefinitely while redirecting the process output

查看:181
本文介绍了Process.waitforexit()在重定向进程输出时无限期挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,我启动一个应用程序并使用StandardOutput和StandardError读取其输出值并将其写入file.once启动该进程启动两个不同的线程,这些线程从流中读取输出并设置使用的某些字符串通过主线程将其写入outout文件。有时(非常罕见的情况)process.waitforexit()不会返回并无限期地等待。

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.

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;
            }
        }



请注意,在错误的情况下,只有在我手动终止进程后才返回进程,所以我猜这是一些死锁问题。任何人都可以帮我解决这个问题吗?



我尝试了什么:



我在 c# - ProcessStartInfo挂在WaitForExit上时遇到了类似的问题?为什么? - Stack Overflow [ ^ ]但是如果我遇到同样的问题就无法解决。


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?

What I have tried:

I have gone through similar questions at c# - ProcessStartInfo hanging on "WaitForExit"? Why? - Stack Overflow[^] but cant relate if I have the same issue.

推荐答案

首先使用调试器,然后找出你传递给Process.Start的确切内容。 />
过程是什么?有什么争论?什么是最终的超时值?



如果一切正常,那么首先尝试使用CMD提示运行该过程:它做了什么,发生了什么?它终止了吗?

然后开始手动调整事情:使用调试器将超时覆盖到几秒钟,然后查看它是否停止。



基本上,玩它:获取信息。目前,您拥有的代码在很大程度上依赖于外部世界 - 无论是在输入参数还是系统配置方面 - 并且这些代码无法正常工作,因为您需要先完成三个部分(第三个是您的代码)隔离问题的实际位置,调试器是唯一可以帮助您实现此目的的工具。我们不能为您做任何事情,因为我们只能访问三元组的一部分:您的代码如上所示。我们无法在您的确切条件下运行它!
Start by using the debugger, and find out exactly what you are passing to Process.Start
What is the process? What are the arguments? What is the timeout value ending up as?

If it all looks right, then firstly try running the process using a CMD prompt: what does it do, what happened? Did it terminate?
Then start manually tweaking things: use the debugger to override the timeout to a couple of seconds, and see if it stops then.

Basically, play with it: get information. At the moment, you have code which depends so heavily on the outside world - both in terms of input parameters and system configuration - and that doesn't work because some part of the three (the third being your code) that you need to first isolate where the problem actually is, and the debugger is the only tool that can help you do that. We can't do any of it for you, because we only have access to one part of the triplet: your code as shown above. And we can't run that under your exact conditions!


这篇关于Process.waitforexit()在重定向进程输出时无限期挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆