如何在 C# 中异步读取以结束进程输出? [英] How to read to end process output asynchronously in C#?

查看:36
本文介绍了如何在 C# 中异步读取以结束进程输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C# 中异步读取一个 Process 的输出时遇到问题.我在这个网站上发现了一些其他类似的问题,但它们并没有真正帮助我.这是我所做的:

I have problem with reading the output of one Process asynchronously in C#. I found some other similar questions on this site but they don't really help me. Here is what I do:

  1. 创建新流程
  2. 设置启动信息-文件名、参数、CreateNoWindow(true)、UseShellExecute(false)、RedirectStandardOutput(true)
  3. 向OutputDataReceived添加事件处理程序;
  4. 启动进程,BeginOutputReadLine 然后WaitForExit().

它工作正常,但启动进程的输出写了一些我想得到的百分比(%),但我不能,因为我的代码逐行读取并且百分比不显示

It works fine but the output of the started process writes some percents(%) which I want to get but I can't since my code reads line by line and the percents don't show up.

示例:

%0,%1...%100
Finished.

我的输出:

%0
Finished. 

这是我程序的当前代码:

Here is the current code of my program:

StringBuilder sBuilder = new StringBuilder();
static void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    sBuilder.AppendLine(e.Data);
}

static void CommandExecutor()
{
    Process process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = /*path of the program*/,
            Arguments = /*arguments*/,
            CreateNoWindow = true,
            UseShellExecute = false,
            WindowStyle = ProcessWindowStyle.Hidden,
            RedirectStandardOutput = true
        }
    };

    process.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);

    process.Start();

    process.BeginOutputReadLine();

    process.WaitForExit();
}

推荐答案

Process.WaitForExit() 将等待异步输出/错误流读取完成.不幸的是,对于 Process.WaitForExit(timeout) 重载,情况并非如此.这是 Process 类在内部所做的:

Process.WaitForExit() will wait until the asynchronous output / error stream reading finished. Unfortunately this is not true for Process.WaitForExit(timeout) overload. This is what the Process class does internally:

//...

finally
{
    if (processWaitHandle != null)
    {
        processWaitHandle.Close();
    }
    if (this.output != null && milliseconds == -1)
    {
        this.output.WaitUtilEOF();
    }
    if (this.error != null && milliseconds == -1)
    {
        this.error.WaitUtilEOF();
    }
    this.ReleaseProcessHandle(safeProcessHandle);
}

...所以它只会在没有超时的情况下等待异步读取!要修复它,只需在 WaitForExit(timeout) 返回 true 后调用 parameterless WaitForExit():

... So it will wait for the async reads only if there was no timeout! To fix it simply call the parameterless WaitForExit() after WaitForExit(timeout) returned true:

//...

if (process.WaitForExit( 10 * 1000 ) && process.WaitForExit() )
{
 // Process'es OutputDataReceived / ErrorDataReceived callbacks will not be called again, EOF streams reached
}
else
{
   throw new Exception("timeout");
}

有关详细信息,请阅读此处的备注:http:///msdn.microsoft.com/en-us/library/ty0d8k56%28v=vs.110%29

For details read the remarks here: http://msdn.microsoft.com/en-us/library/ty0d8k56%28v=vs.110%29

这篇关于如何在 C# 中异步读取以结束进程输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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