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

发布于 2024-12-10 22:33:22 字数 1175 浏览 0 评论 0原文

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

protected virtual void OnBtnPlayClicked (object sender, System.EventArgs e) { 字符串参数 = filechooser.Filename; 字符串输出=“”; 字符串错误 = 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;

        }
    }   

我哪里错了?

谢谢

i'm trying to write a simple software who play karaoke in Mono Gtk / .NET.
I simply want to run via shell something like "timidity filename.kar" (timidity is a software synth).
I want to write timidity output into a textview, but the problem is that if i run this code, timidity start to 'play' but the app exits

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;

        }
    }   

Where i'm wrong ?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不必了 2024-12-17 22:33:22

您正在尝试 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();

You are attempting to ReadToEnd of the spawned process's standard output, which will block until that process closes its standard output stream. In this case, this will be when the process terminates.

What you need to do instead is redirect the standard output and read chunks out of it as they become available using BeginOutputReadLine.

For example:

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();
谁的新欢旧爱 2024-12-17 22:33:22

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

执行命令提示进程 asnyc 并获取结果

If you want to work fully async I suggest something like what I detailed here in another post like this, seperate thread and event driven.

Execute command promt process asnyc and get result

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文