关于执行外部进程



我需要运行一些外部exe,并读取其输出和错误。

            prc = new Process();
            prc.StartInfo.UseShellExecute = false;
            prc.StartInfo.FileName = fileName;
            prc.StartInfo.Arguments = arguments;
            prc.StartInfo.LoadUserProfile = true;
            prc.StartInfo.RedirectStandardOutput = true;
            prc.StartInfo.RedirectStandardError = true;
            prc.OutputDataReceived += (sendingProcess, outLine) => outputText.AppendLine(outLine.Data);
            prc.ErrorDataReceived += (sendingProcess, errorLine) => errorText.AppendLine(errorLine.Data);
            prc.Start();
            prc.BeginOutputReadLine();
            prc.BeginErrorReadLine();

发生这种情况的线程可能随时中止,我无法对其进行任何更改,因此我无法使用prc.WaitForExit();因为它无法中止,直到进程本身被杀死。这意味着每次线程中止时,所有执行都会挂起。

所以我在单独的方法中用这个替换了它:

while (!Thread.CurrentThread.ThreadState.HasFlag(ThreadState.AbortRequested) && !Thread.CurrentThread.ThreadState.HasFlag(ThreadState.Aborted))
        {
            if (!process.HasExited) continue;
            return process.ExitCode;
        }

唯一的问题是输出。奇怪的是,有时输出和错误最终都会缺少字符串,添加Thread.Sleep可以解决这个问题,这意味着异步写入由于某种原因无法跟上。

这似乎是一个微不足道的问题,但我找不到可靠的解决方案。 Thread.Sleep几乎不是一个好的做法,执行时间非常重要。可靠地获取所有错误和输出的最佳方法是什么?

输出的问题在于,在进程退出之前,用于将其传送到进程的匿名管道的写入端可能不会被刷新 - 它并不总是发生,但你不能依赖它没有发生。相反,为什么不在单独的线程中运行进程内容,包括WaitForExit()(或者只是WaitForExit()(?您的原始线程可以等待该工作线程以Thread.Abort可能的方式完成(例如 Thread.Join() (,您将拥有完整的输出。或者,如果您不担心ThreadAbortException但需要能够取消WaitForExit()呼叫,则可以使用 WaitHandle.WaitAny(prc.Handle,cancellationToken.WaitHandle)

相关内容

  • 没有找到相关文章

最新更新