首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#处理实时StandardOutput流

C#处理实时StandardOutput流
EN

Stack Overflow用户
提问于 2021-07-03 21:53:34
回答 1查看 46关注 0票数 0

我正在尝试使用Process从我的C#项目中调用rclone,并且还需要从该过程中获得实时输出。

为了实现这一点,我使用下面的代码,可以找到下面的代码:

它是从this post上取来的。

代码语言:javascript
复制
using System;
using System.IO;

namespace Collection_Manager
{
    /// <summary>
    /// Stream reader for StandardOutput and StandardError stream readers
    /// Runs an eternal BeginRead loop on the underlaying stream bypassing the stream reader.
    /// 
    /// The TextReceived sends data received on the stream in non delimited chunks. Event subscriber can
    /// then split on newline characters etc as desired.
    /// </summary>
    class AsyncStreamReader
    {

        public delegate void EventHandler<args>(object sender, string Data);
        public event EventHandler<string> DataReceived;

        protected readonly byte[] buffer = new byte[4096];
        private StreamReader reader;


        /// <summary>
        ///  If AsyncStreamReader is active
        /// </summary>
        public bool Active { get; private set; }


        public void Start()
        {
            if (!Active)
            {
                Active = true;
                BeginReadAsync();
            }
        }


        public void Stop()
        {
            Active = false;
        }


        public AsyncStreamReader(StreamReader readerToBypass)
        {
            reader = readerToBypass;
            Active = false;
        }


        protected void BeginReadAsync()
        {
            if (Active)
            {
                reader.BaseStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), null);
            }
        }

        private void ReadCallback(IAsyncResult asyncResult)
        {
            int bytesRead = reader.BaseStream.EndRead(asyncResult);

            string data = null;

            //Terminate async processing if callback has no bytes
            if (bytesRead > 0)
            {
                data = reader.CurrentEncoding.GetString(buffer, 0, bytesRead);
            }
            else
            {
                //callback without data - stop async
                Active = false;
            }

            //Send data to event subscriber - null if no longer active
            if (DataReceived != null)
            {
                DataReceived.Invoke(this, data);
            }

            //Wait for more data from stream
            BeginReadAsync();
        }


    }
}

我使用以下命令来调用它:

代码语言:javascript
复制
logHandler.writeLogToBuffer();

uploadProcess.StartInfo.UseShellExecute = false;
uploadProcess.StartInfo.CreateNoWindow = true;            uploadProcess.StartInfo.RedirectStandardOutput = true;
uploadProcess.StartInfo.FileName = "rclone.exe";
uploadProcess.StartInfo.StandardOutputEncoding = Encoding.UTF8;
uploadProcess.StartInfo.Arguments =
                "sync -P " +
                "\"" + sourceDirectory + "\" " +
                "\"" + Properties.Settings.Default.remoteName + "/" + destination + "\" " +
                "--exclude '.*{/**,}' " +
                "--config \"" + Properties.Settings.Default.rcloneConfig + "\" " +
                Properties.Settings.Default.rcloneArgs;

uploadProcess.Start();

AsyncStreamReader stdOut = new AsyncStreamReader(uploadProcess.StandardOutput);
stdOut.DataReceived += (sender, data) =>
{
    if (!string.IsNullOrEmpty(data))
    {
        if (data.Contains("ETA"))
        {
            logHandler.loadLogFromBuffer();
        }
        logHandler.writeToLog(data);
    }
};
stdOut.Start();

然而,我遇到的问题是流的第一个字节(来自Transferring:...T消息)与流的其余部分分开输出。

loghandler只是我编写的一个方法,用于在UI线程上写入WPF richtextbox。writeToLog(string message);只是将一行附加到RTB,writeLogToBuffer();将日志写到可以加载的缓冲区,以便用loadLogFromBuffer();加载RTB内容。

那么,这里的问题是什么呢?这是rclone的怪癖吗?我该如何着手解决这个问题?提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2021-07-03 22:48:06

您可以在进程中使用EnableRaisingEvents属性。将其设置为true并调用BeginOutputReadLine()方法以启动输出侦听。然后您就可以使用OutputDataReceived事件了。每当数据传入时,都会触发此事件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68236890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档