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

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

问题描述

我有问题,在C#异步读取一个进程的输出。
我发现本网站上的一些其他类似的问题,但他们并不真正帮助我。
这是我做的:


  1. 请新工艺

  2. 设置的StartInfo
    -FileName,参数,CreateNoWindow(真),UseShellExecute(假),RedirectStandardOutput(真)

  3. 事件处理程序添加到OutputDataReceived;

  4. 启动过程中,BeginOutputReadLine然后WaitForExit()。

它工作正常,但启动过程的输出写入一些百分比(),我想,但我不能因为我的code读取行通过线与百分比不显示。

例如:

  0%,1%... 100%
成品。

我的输出:

  0%
成品。

下面是我的程序的当前code:

 的StringBuilder sBuilder =新的StringBuilder();
静态无效proc_OutputDataReceived(对象发件人,DataReceivedEventArgs E)
{
    sBuilder.AppendLine(e.Data);
}静态无效CommandExecutor()
{
    工艺过程=新工艺
    {
        StartInfo的=新的ProcessStartInfo
        {
            文件名= / *程序* /路径,
            参数= / * *参数/,
            CreateNoWindow = TRUE,
            UseShellExecute =假,
            WindowStyle = ProcessWindowStyle.Hidden,
            RedirectStandardOutput =真
        }
    };    process.OutputDataReceived + =新DataReceivedEventHandler(proc_OutputDataReceived);    的Process.Start();    process.BeginOutputReadLine();    process.WaitForExit();
}


解决方案

看来,读书流输出异步有点破 - 不是所有的数据都在进程退出之前读取。即使你叫 Process.WaitForExit(),即使你再调用 Process.Close()(或的Dispose()),你仍然可以得到大量的数据之后。见的http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/一个完整的写了,但解决的办法基本上是使用同步的方法。为了避免死锁,但是,你必须调用其中的一个在另一个线程:

 使用(VAR工艺=的Process.Start(processInfo))
{
    //读取标准错误同步(在另一个线程)    字符串ERRORTEXT = NULL;
    VAR stderrThread =新的Thread(()=> {ERRORTEXT = process.StandardError.ReadToEnd();});
    stderrThread.Start();    //标准输出同步读取(在此线程)    而(真)
    {
        变种线= process.StandardOutput.ReadLine();
        如果(行== NULL)
            打破;        // ...做一些与此行...
    }    process.WaitForExit();
    stderrThread.Join();    // ...在这里,你可以做一些与ERRORTEXT ...
}

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. Make new process
  2. Set startinfo -FileName, Arguments, CreateNoWindow(true), UseShellExecute(false), RedirectStandardOutput(true)
  3. Add event handler to OutputDataReceived;
  4. Start process, BeginOutputReadLine and then 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.

Example:

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

My output:

%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();
}

解决方案

It seems that reading stream output asynchronously is a bit broken - not all the data is read before the process exits. Even if you call Process.WaitForExit() and even if you then call Process.Close() (or Dispose()) you can still get a lot of data afterwards. See http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/ for a full write-up, but the solution is basically to use synchronous methods. To avoid a deadlock, though, you have to call one of them on another thread:

using (var process = Process.Start(processInfo))
{
    // Read stderr synchronously (on another thread)

    string errorText = null;
    var stderrThread = new Thread(() => { errorText = process.StandardError.ReadToEnd(); });
    stderrThread.Start();

    // Read stdout synchronously (on this thread)

    while (true)
    {
        var line = process.StandardOutput.ReadLine();
        if (line == null)
            break;

        // ... Do something with the line here ...
    }

    process.WaitForExit();
    stderrThread.Join();

    // ... Here you can do something with errorText ...
}

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

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