阅读过程的输出延迟时,异步 [英] Delays when reading process output asynchronously

查看:93
本文介绍了阅读过程的输出延迟时,异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用.NET和C#来启动一个进程,并读出它的输出是异步的。我的问题是,似乎有一个延迟的输出是通过我的程序读取之前。如果我运行在命令行上的可执行文件,还有立即输出,当它开始运行。但是,当我运行使用我的code它ReadOutput事件处理函数不是调用,直到进程退出。我想用这个来提供过程的输出的实时视图,所以我不想等待(几分钟),直到进程退出。

下面是一些相关的code:

  MyProcess =新工艺();
MyProcess.StartInfo.FileName =命令;
MyProcess.StartInfo.Arguments = ARGS;
MyProcess.StartInfo.UseShellExecute = FALSE;
MyProcess.StartInfo.RedirectStandardOutput = TRUE;
MyProcess.StartInfo.RedirectStandardError = TRUE;
MyProcess.StartInfo.RedirectStandardInput = TRUE;
MyProcess.OutputDataReceived + =新DataReceivedEventHandler(ReadOutput);
MyProcess.ErrorDataReceived + =新DataReceivedEventHandler(ReadOutput);

如果(!MyProcess.Start())
{
    抛出新的异常(进程无法启动);
}

尝试
{
    MyProcess.BeginOutputReadLine();
    MyProcess.BeginErrorReadLine();
}
赶上(例外前)
{
    抛出新的异常(无法开始异步读取的过程;
}
 

这是我的事件处理程序:

 私人无效ReadOutput(对象sendingProcess,DataReceivedEventArgs大纲)
{
    OutputBuilder.AppendLine(outLine.Data);
    Console.WriteLine(outLine.Data);
    Console.Out.Flush();
}
 

解决方案

这是我做的方式(C#3)按使用lambda语法我的评论。

  ///<总结>
    ///收集从启动程序标准输出的文本。
    ///< /总结>
    私人静态只读的StringBuilder的outputText =新的StringBuilder();

    ///<总结>
    ///收集从启动程序标准错误文本。
    ///< /总结>
    私人静态只读StringBuilder的ERRORTEXT =新的StringBuilder();

    ///<总结>
    ///程序的入口点。
    ///< /总结>
    ///< PARAM NAME =的args>的命令行参数< /参数>
    ///<返回>将出口code< /回报>
    私有静态诠释的主要(字串[] args)
    {
        使用(VAR方法=的Process.Start(新的ProcessStartInfo(
            PROGRAM.EXE
            参数)
            {
                CreateNoWindow = TRUE,
                ErrorDialog =假,
                RedirectStandardError = TRUE,
                RedirectStandardOutput = TRUE,
                UseShellExecute =假
            }))
        {
            process.OutputDataReceived + =(sendingProcess,轮廓)=>
                outputText.AppendLine(outLine.Data);

            process.ErrorDataReceived + =(sendingProcess,errorLine)=>
                errorText.AppendLine(errorLine.Data);

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
            Console.WriteLine(errorText.ToString());
            Console.WriteLine(outputText.ToString());
            返回process.Exit code;
        }
 

I am using .NET and C# to start a process and read it's output asynchronously. My problem is that there seems to be a delay before the output is read by my program. If I run the executable on the command line, there is output immediately when it starts running. But when I run it using my code the ReadOutput event handler isn't called until the Process exits. I want to use this to provide a real-time view of the process's output, so I don't want to wait (several minutes) until the process exits.

Here's some relevant code:

MyProcess = new Process();
MyProcess.StartInfo.FileName = command;
MyProcess.StartInfo.Arguments = args;
MyProcess.StartInfo.UseShellExecute = false;
MyProcess.StartInfo.RedirectStandardOutput = true;
MyProcess.StartInfo.RedirectStandardError = true;
MyProcess.StartInfo.RedirectStandardInput = true;
MyProcess.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
MyProcess.ErrorDataReceived += new DataReceivedEventHandler(ReadOutput);

if (!MyProcess.Start())
{
    throw new Exception("Process could not be started");
}

try
{
    MyProcess.BeginOutputReadLine();
    MyProcess.BeginErrorReadLine();
}
catch (Exception ex)
{
    throw new Exception("Unable to begin asynchronous reading from process";
}

And here's my event handler:

private void ReadOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
    OutputBuilder.AppendLine(outLine.Data);
    Console.WriteLine(outLine.Data);
    Console.Out.Flush();
}

解决方案

This is the way I do it (C# 3) as per my comment using the lambda syntax.

    /// <summary>
    /// Collects standard output text from the launched program.
    /// </summary>
    private static readonly StringBuilder outputText = new StringBuilder();

    /// <summary>
    /// Collects standard error text from the launched program.
    /// </summary>
    private static readonly StringBuilder errorText = new StringBuilder();

    /// <summary>
    /// The program's entry point.
    /// </summary>
    /// <param name="args">The command-line arguments.</param>
    /// <returns>The exit code.</returns>
    private static int Main(string[] args)
    {
        using (var process = Process.Start(new ProcessStartInfo(
            "program.exe",
            args)
            {
                CreateNoWindow = true,
                ErrorDialog = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                UseShellExecute = false
            }))
        {
            process.OutputDataReceived += (sendingProcess, outLine) =>
                outputText.AppendLine(outLine.Data);

            process.ErrorDataReceived += (sendingProcess, errorLine) =>
                errorText.AppendLine(errorLine.Data);

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
            Console.WriteLine(errorText.ToString());
            Console.WriteLine(outputText.ToString());
            return process.ExitCode;
        }

这篇关于阅读过程的输出延迟时,异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆