【问题标题】:Process hangs on WaitForExit when using Sox and pushing to stdout使用 Sox 并推送到标准输出时,进程在 WaitForExit 上挂起
【发布时间】:2016-04-18 15:00:38
【问题描述】:

我通过在 c# 程序中调用进程来使用 sox。我知道挂在 WaitForExit 或 Start 方法上很受欢迎,但我无法处理它。也许我从负责运行进程的代码开始(这是从this topic 中评价最高的答案复制和粘贴:

using (Process process = new Process())
{
    process.StartInfo.FileName = _soxExePath;
    process.StartInfo.Arguments = _task.Arguments.RemoveFirstOccurence("sox");
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;

    StringBuilder output = new StringBuilder();
    StringBuilder error = new StringBuilder();

    using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
    using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
    {
        process.OutputDataReceived += (sender, e) =>
        {
            if (e.Data == null)
            {
                outputWaitHandle.Set();
            }
            else
            {
                output.AppendLine(e.Data);
            }
        };
        process.ErrorDataReceived += (sender, e) =>
        {
            if (e.Data == null)
            {
                errorWaitHandle.Set();
            }
            else
            {
                error.AppendLine(e.Data);
            }
        };

        process.Start();

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        if (process.WaitForExit(timeout) &&
            outputWaitHandle.WaitOne(timeout) &&
            errorWaitHandle.WaitOne(timeout))
        {
            result = process.ExitCode == 0;
        }
        else
        {
            // Timed out.
        }
    }
}

如您所见,标准输出是异步处理的,但程序仍会在 WaitForExit 上挂起(即使超时设置为 100000)。当我在 Windows cmd 中键入完全相同的命令时,处理时间不到一秒,所以这不是什么大操作。

sox --combine mix 1.wav 2.wav 3.wav -p | sox - --combine concatenate 4.wav output.wav << causing problem

我知道这是因为 Sox 正在为 stdout 创建第一个操作。当我尝试一些立即保存到文件的命令时,没有问题。

sox --combine mix 1.wav 2.wav 3.wav output.wav << no problem

【问题讨论】:

  • 您是否从 sox 程序中获得任何日志记录?

标签: c# process freeze sox


【解决方案1】:

答案在于你如何称呼 sox。我猜你也没有完全得到你期望的输出等等。

 process.StartInfo.FileName = _soxExePath;
 process.StartInfo.Arguments = _task.Arguments.RemoveFirstOccurence("sox");
 process.StartInfo.UseShellExecute = false;
 process.StartInfo.RedirectStandardOutput = true;
 process.StartInfo.RedirectStandardError = true;
 process.EnableRaisingEvents = true;
  //<set event handlers here>
 process.Exited += // define what to do to clear up
 process.Start();

有两个区别,一是开启引发事件发送和接收任何输出和输入,你应该只需要设置接收的输出数据,你似乎没有发送新的东西。此外,通过监听出口,您可以处理一切都结束的事实......而不是挂起您的应用程序希望听到它完成......

【讨论】:

    【解决方案2】:

    我的解决方案是 here ,只需调用 cmd 作为 Process 并将路径传递给可执行文件和 sox 的参数作为进程参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2017-08-11
      • 2022-01-05
      • 2012-12-29
      • 1970-01-01
      相关资源
      最近更新 更多