【问题标题】:C# RedirectStandardOutput output and weaitforexitC# RedirectStandardOutput 输出和 weaitforexit
【发布时间】:2016-05-10 06:55:05
【问题描述】:

我有以下情况。我需要使用 Process() 在 c# 中运行一些 bat 文件,并且需要将其输出结束错误重定向到文件。我知道该怎么做,如果我的进程不使用超时,我的代码可以正常工作。所以程序一直工作到进程结束(我期望的是进程在超时后被杀死)。以下是我的代码。

Process TcRunner = new Process();
TcRunner.StartInfo.FileName = "cmd.bat";
TcRunner.EnableRaisingEvents = true;
TcRunner.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
TcRunner.StartInfo.UseShellExecute = false;
TcRunner.StartInfo.RedirectStandardOutput = true;
TcRunner.StartInfo.RedirectStandardError = true;

try
{
     TcRunner.Start();
}
catch (Exception ex)
{
     Program.Print("Error: Could not start process\n");
     return 1;
}

string run_log_out = TcRunner.StandardOutput.ReadToEnd();
string run_log_err = TcRunner.StandardError.ReadToEnd();

if (!TcRunner.WaitForExit(5000)
{
    //kill the process
}

try
{
    StreamWriter run_out = new StreamWriter(@".\out");
    StreamWriter run_err = new StreamWriter(@".\err");
    run_out.WriteLine(run_log_out);
    run_err.WriteLine(run_log_err);
    run_out.Close();
    run_err.Close();
}
catch (Exception e)
{
    Console.WriteLine("Cannot open out/err for writing");
}

【问题讨论】:

  • 你能再解释一下这个问题吗?
  • 程序挂起行 string run_log_out = TcRunner.StandardOutput.ReadToEnd();直到进程结束,然后移动到 waitforexit(timeout) 行。因此,如果我有 5 秒超时并且我的命令运行时间是 10 秒,则该进程将不会被杀死

标签: c# redirectstandardoutput waitforexit


【解决方案1】:

如果您想同时读取两个流,则可能会出现死锁。因此,您应该尝试异步读取至少一个流。

ProcessStartInfo.RedirectStandardOutput 的 VisualStudio 帮助中,我找到了以下信息:

   // Do not perform a synchronous read to the end of both
   // redirected streams.
   // string output = p.StandardOutput.ReadToEnd();
   // string error = p.StandardError.ReadToEnd();
   // p.WaitForExit();
   // Use asynchronous read operations on at least one of the streams.
   p.BeginOutputReadLine();
   string error = p.StandardError.ReadToEnd();
   p.WaitForExit();

link 有一个很好的例子,他们通过将方法绑定到事件来异步读取两个流:

...
build.StartInfo.RedirectStandardOutput = true;
build.StartInfo.RedirectStandardError = true;
...
build.ErrorDataReceived += build_ErrorDataReceived;
build.OutputDataReceived += build_ErrorDataReceived;
...
build.BeginOutputReadLine();
build.BeginErrorReadLine();

static void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    ...
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    相关资源
    最近更新 更多