如何在不阻塞执行的情况下编写System.Diagnostic.Process输出?

时间:2011-10-19 14:45:46

标签: .net process

我正在尝试编写一个在Mono Gtk / .NET中播放卡拉OK的简单软件。 我只想通过shell运行类似“timidity filename.kar”的东西(胆怯是一种软件合成器)。 我想将胆怯输出写入textview,但问题是,如果我运行此代码,胆怯开始“播放”但应用程序退出

protected virtual void OnBtnPlayClicked(object sender,System.EventArgs e)     {         string parms = filechooser.Filename;         string output =“”;         string error = string.Empty;

    ProcessStartInfo psi = new ProcessStartInfo("timidity", parms);

    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
    psi.UseShellExecute = false;

    System.Diagnostics.Process reg;
    reg = System.Diagnostics.Process.Start(psi);

    reg.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
reg.BeginOutputReadLine();     // HERE THE APP GO CRASH

}

  private void SortOutputHandler(object sendingProcess, 
        DataReceivedEventArgs outLine)
    {
        // Collect the sort command output.
        if (!String.IsNullOrEmpty(outLine.Data))
        {                
            txtOutput.Buffer.Text =txtOutput.Buffer.Text + outLine.Data;

        }
    }   

我哪里错了?

由于

2 个答案:

答案 0 :(得分:2)

您正在尝试ReadToEnd生成进程的标准输出,该输出将阻塞,直到该进程关闭其标准输出流。在这种情况下,这将是流程终止的时间。

您需要做的是重定向标准输出,并在使用BeginOutputReadLine时可以使用它们读取块。

例如:

psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
reg = System.Diagnostics.Process.Start(psi);
reg.OutputDataReceived += (sender, args) => 
                          Console.WriteLine("received output: {0}", args.Data);
reg.BeginOutputReadLine();

答案 1 :(得分:0)

如果你想完全异步工作,我建议像我在另一篇文章中详述的那样,单独的线程和事件驱动。

Execute command promt process asnyc and get result