Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行命令提示符.exe应用程序时,在C#WPF应用程序中定义特定行的超时_C#_.net_Wpf_Software Design - Fatal编程技术网

在运行命令提示符.exe应用程序时,在C#WPF应用程序中定义特定行的超时

在运行命令提示符.exe应用程序时,在C#WPF应用程序中定义特定行的超时,c#,.net,wpf,software-design,C#,.net,Wpf,Software Design,在我的主WPF应用程序代码中,我需要在命令提示符下运行.exe应用程序。此操作在backgroundworker内部执行,我有以下代码。代码在命令提示符下运行readlines.exe应用程序,并将输出行读取为字符串(str) 我想将超时添加到下一行,这样当超时结束时,进程将被取消(作为CTR+C),并且“str”将获得输出文本,直到此时为止 str = proc1.StandardOutput.ReadToEnd(); 有可能吗?一些示例如何实现这一点(注意,代码未经测试,可以改进)) 这个

在我的主WPF应用程序代码中,我需要在命令提示符下运行.exe应用程序。此操作在backgroundworker内部执行,我有以下代码。代码在命令提示符下运行readlines.exe应用程序,并将输出行读取为字符串(str)

我想将超时添加到下一行,这样当超时结束时,进程将被取消(作为CTR+C),并且“str”将获得输出文本,直到此时为止

str = proc1.StandardOutput.ReadToEnd();

有可能吗?

一些示例如何实现这一点(注意,代码未经测试,可以改进)

这个类看起来像:

public class ProcessOutputReader
{
    public ProcessOutputReader(Process process)
    {
        this.Process = process;
        this.Lines = new List<string>();
    }

    public List<string> Lines
    {
        get;
        private set;
    }

    public Process Process
    {
        get;
        private set;
    }

    private Thread ReaderThread
    {
        get;
        set;
    }

    public void StartReading()
    {
        if (this.ReaderThread == null)
        {
            this.ReaderThread = new Thread(new ThreadStart(ReaderWorker));
        }

        if (!this.ReaderThread.IsAlive)
        {
            this.ReaderThread.Start();
        }
    }

    public void StopReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                this.ReaderThread.Abort();
                this.ReaderThread.Join();
            }
        }
    }

    private void ReaderWorker()
    {
        try
        {
            while (!this.Process.HasExited)
            {
                string data = this.Process.StandardOutput.ReadLine();
                this.Lines.Add(data);
            }
        }
        catch (ThreadAbortException)
        {
            if (!this.Process.HasExited)
            {
                this.Process.Kill();
            }
        }
    }
}
公共类ProcessOutputReader
{
公共ProcessOutputReader(进程)
{
这个过程=过程;
this.Lines=新列表();
}
公共列表行
{
得到;
私人设置;
}
公共程序
{
得到;
私人设置;
}
私有线程读取器线程
{
得到;
设置
}
公共空间开始踏步()
{
if(this.ReaderThread==null)
{
this.ReaderThread=新线程(新线程开始(ReaderWorker));
}
如果(!this.ReaderThread.IsAlive)
{
this.ReaderThread.Start();
}
}
公众作废停止阅读()
{
if(this.ReaderThread!=null)
{
if(this.ReaderThread.IsAlive)
{
this.ReaderThread.Abort();
this.ReaderThread.Join();
}
}
}
私有void ReaderWorker()
{
尝试
{
而(!this.Process.hasExit)
{
字符串数据=this.Process.StandardOutput.ReadLine();
此.Lines.Add(数据);
}
}
捕获(线程异常)
{
如果(!this.Process.hasExit)
{
this.Process.Kill();
}
}
}
}

尽管前面的答案已经被接受,但这里可能是一个更有用、更安全、更高效的解决方案。此外,它不使用
ReadLine()
方法,该方法会一直阻塞直到写入一行(可能永远不会发生)。它使用
StringBuilder
的实例,并以可指定的数据块(默认大小为128个字符)从流中读取数据。此外,它还支持基于事件的读取数据通知

类的用法保持不变

ProcessOutputReader por = new ProcessOutputReader(proc1);
por.StartReading();

// Do whatever you want here
// (e.g. sleep or whatever)

por.StopReading();

// Now you have everything that has been read in por.Data
但是,我添加了
OnDataRead
事件,每次读取新数据时都会触发该事件。您可以使用以下代码访问数据:

...
// Subscribe to the event
por.OnDataRead += OnDataReadEventHandler;
...
回调方法/事件处理程序如下所示:

private void OnDataReadEventHandler(object sender, ProcessOutputReaderEventArgs e)
{
    // e.IntermediateDataStore points to the StringBuilder instance which holds
    // all the data that has been received until now.
    string completeData = e.IntermediateDataStore.ToString();

    // e.NewData points to a string which contains the data that has been received
    // since the last triggered event (because the event is triggered on each read).
    string newData = e.NewData;
}
/// <summary>
/// Represents the ProcessOutputReader class.
/// </summary>
public class ProcessOutputReader
{
    /// <summary>
    /// Represents the instance of the thread arguments class.
    /// </summary>
    private ProcessOutputReaderWorkerThreadArguments threadArguments;

    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReader"/> class.
    /// </summary>
    /// <param name="process">The process which's output shall be read.</param>
    /// <exception cref="System.ArgumentOutOfRangeException">Is thrown if the specified process reference is null.</exception>
    public ProcessOutputReader(Process process)
    {
        if (process == null)
        {
            throw new ArgumentOutOfRangeException("process", "The parameter \"process\" must not be null");
        }

        this.Process = process;
        this.IntermediateDataStore = new StringBuilder();
        this.threadArguments = new ProcessOutputReaderWorkerThreadArguments(this.Process, this.IntermediateDataStore);
    }

    /// <summary>
    /// Is fired whenever data has been read from the process output.
    /// </summary>
    public event EventHandler<ProcessOutputReaderEventArgs> OnDataRead;

    /// <summary>
    /// Gets or sets the worker thread.
    /// </summary>
    private Thread ReaderThread
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the intermediate data store.
    /// </summary>
    private StringBuilder IntermediateDataStore
    {
        get;
        set;
    }

    /// <summary>
    /// Gets the data collected from the process output.
    /// </summary>
    public string Data
    {
        get
        {
            return this.IntermediateDataStore.ToString();
        }
    }

    /// <summary>
    /// Gets the process.
    /// </summary>
    public Process Process
    {
        get;
        private set;
    }

    /// <summary>
    /// Stars reading from the process output.
    /// </summary>
    public void StartReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                return;
            }
        }

        this.ReaderThread = new Thread(new ParameterizedThreadStart(ReaderWorker));
        this.threadArguments.Exit = false;
        this.ReaderThread.Start(this.threadArguments);
    }

    /// <summary>
    /// Stops reading from the process output.
    /// </summary>
    public void StopReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                this.threadArguments.Exit = true;
                this.ReaderThread.Join();
            }
        }
    }

    /// <summary>
    /// Fires the OnDataRead event.
    /// </summary>
    /// <param name="newData">The new data that has been read.</param>
    protected void FireOnDataRead(string newData)
    {
        if (this.OnDataRead != null)
        {
            this.OnDataRead(this, new ProcessOutputReaderEventArgs(this.IntermediateDataStore, newData));
        }
    }

    /// <summary>
    /// Represents the worker method.
    /// </summary>
    /// <param name="data">The thread arguments, must be an instance of the <see cref="ProcessOutputReaderWorkerThreadArguments"/> class.</param>
    private void ReaderWorker(object data)
    {
        ProcessOutputReaderWorkerThreadArguments args;

        try
        {
            args = (ProcessOutputReaderWorkerThreadArguments)data;
        }
        catch
        {
            return;
        }

        try
        {
            char[] readBuffer = new char[args.ReadBufferSize];

            while (!args.Exit)
            {
                if (args.Process == null)
                {
                    return;
                }

                if (args.Process.HasExited)
                {
                    return;
                }

                if (args.Process.StandardOutput.EndOfStream)
                {
                    return;
                }

                int readBytes = this.Process.StandardOutput.Read(readBuffer, 0, readBuffer.Length);
                args.IntermediateDataStore.Append(readBuffer, 0, readBytes);

                this.FireOnDataRead(new String(readBuffer, 0, readBytes));
            }
        }
        catch (ThreadAbortException)
        {
            if (!args.Process.HasExited)
            {
                args.Process.Kill();
            }
        }
    }
}
/// <summary>
/// Represents the ProcessOutputReaderWorkerThreadArguments class.
/// </summary>
public class ProcessOutputReaderWorkerThreadArguments
{
    /// <summary>
    /// Represents the read buffer size,
    /// </summary>
    private int readBufferSize;

    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReaderWorkerThreadArguments"/> class.
    /// </summary>
    /// <param name="process">The process.</param>
    /// <param name="intermediateDataStore">The intermediate data store.</param>
    public ProcessOutputReaderWorkerThreadArguments(Process process, StringBuilder intermediateDataStore)
    {
        this.ReadBufferSize = 128;
        this.Exit = false;
        this.Process = process;
        this.IntermediateDataStore = intermediateDataStore;
    }

    /// <summary>
    /// Gets or sets a value indicating whether the thread shall exit or not.
    /// </summary>
    public bool Exit
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the read buffer size in bytes.
    /// </summary>
    /// <exception cref="System.ArgumentOutOfRangeException">Is thrown if the specified value is not greather than 0.</exception>
    public int ReadBufferSize
    {
        get
        {
            return this.readBufferSize;
        }
        set
        {
            if (value <= 0)
            {
                throw new ArgumentOutOfRangeException("value", "The specified value for \"ReadBufferSize\" must be greater than 0.");
            }

            this.readBufferSize = value;
        }
    }

    /// <summary>
    /// Gets the process.
    /// </summary>
    public Process Process
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the intermediate data store.
    /// </summary>
    public StringBuilder IntermediateDataStore
    {
        get;
        private set;
    }
}
/// <summary>
/// Represents the ProcessOutputReaderEventArgs class.
/// </summary>
public class ProcessOutputReaderEventArgs : EventArgs 
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReaderEventArgs"/> class.
    /// </summary>
    /// <param name="intermediateDataStore">The reference to the intermediate data store.</param>
    /// <param name="newData">The new data that has been read.</param>
    public ProcessOutputReaderEventArgs(StringBuilder intermediateDataStore, string newData)
    {
        this.IntermediateDataStore = intermediateDataStore;
        this.NewData = newData;
    }

    /// <summary>
    /// Gets the reference to the intermediate data store.
    /// </summary>
    public StringBuilder IntermediateDataStore
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the new data that has been read.
    /// </summary>
    public string NewData
    {
        get;
        private set;
    }
}
修改后的
ProcessOutputReader
类如下所示:

private void OnDataReadEventHandler(object sender, ProcessOutputReaderEventArgs e)
{
    // e.IntermediateDataStore points to the StringBuilder instance which holds
    // all the data that has been received until now.
    string completeData = e.IntermediateDataStore.ToString();

    // e.NewData points to a string which contains the data that has been received
    // since the last triggered event (because the event is triggered on each read).
    string newData = e.NewData;
}
/// <summary>
/// Represents the ProcessOutputReader class.
/// </summary>
public class ProcessOutputReader
{
    /// <summary>
    /// Represents the instance of the thread arguments class.
    /// </summary>
    private ProcessOutputReaderWorkerThreadArguments threadArguments;

    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReader"/> class.
    /// </summary>
    /// <param name="process">The process which's output shall be read.</param>
    /// <exception cref="System.ArgumentOutOfRangeException">Is thrown if the specified process reference is null.</exception>
    public ProcessOutputReader(Process process)
    {
        if (process == null)
        {
            throw new ArgumentOutOfRangeException("process", "The parameter \"process\" must not be null");
        }

        this.Process = process;
        this.IntermediateDataStore = new StringBuilder();
        this.threadArguments = new ProcessOutputReaderWorkerThreadArguments(this.Process, this.IntermediateDataStore);
    }

    /// <summary>
    /// Is fired whenever data has been read from the process output.
    /// </summary>
    public event EventHandler<ProcessOutputReaderEventArgs> OnDataRead;

    /// <summary>
    /// Gets or sets the worker thread.
    /// </summary>
    private Thread ReaderThread
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the intermediate data store.
    /// </summary>
    private StringBuilder IntermediateDataStore
    {
        get;
        set;
    }

    /// <summary>
    /// Gets the data collected from the process output.
    /// </summary>
    public string Data
    {
        get
        {
            return this.IntermediateDataStore.ToString();
        }
    }

    /// <summary>
    /// Gets the process.
    /// </summary>
    public Process Process
    {
        get;
        private set;
    }

    /// <summary>
    /// Stars reading from the process output.
    /// </summary>
    public void StartReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                return;
            }
        }

        this.ReaderThread = new Thread(new ParameterizedThreadStart(ReaderWorker));
        this.threadArguments.Exit = false;
        this.ReaderThread.Start(this.threadArguments);
    }

    /// <summary>
    /// Stops reading from the process output.
    /// </summary>
    public void StopReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                this.threadArguments.Exit = true;
                this.ReaderThread.Join();
            }
        }
    }

    /// <summary>
    /// Fires the OnDataRead event.
    /// </summary>
    /// <param name="newData">The new data that has been read.</param>
    protected void FireOnDataRead(string newData)
    {
        if (this.OnDataRead != null)
        {
            this.OnDataRead(this, new ProcessOutputReaderEventArgs(this.IntermediateDataStore, newData));
        }
    }

    /// <summary>
    /// Represents the worker method.
    /// </summary>
    /// <param name="data">The thread arguments, must be an instance of the <see cref="ProcessOutputReaderWorkerThreadArguments"/> class.</param>
    private void ReaderWorker(object data)
    {
        ProcessOutputReaderWorkerThreadArguments args;

        try
        {
            args = (ProcessOutputReaderWorkerThreadArguments)data;
        }
        catch
        {
            return;
        }

        try
        {
            char[] readBuffer = new char[args.ReadBufferSize];

            while (!args.Exit)
            {
                if (args.Process == null)
                {
                    return;
                }

                if (args.Process.HasExited)
                {
                    return;
                }

                if (args.Process.StandardOutput.EndOfStream)
                {
                    return;
                }

                int readBytes = this.Process.StandardOutput.Read(readBuffer, 0, readBuffer.Length);
                args.IntermediateDataStore.Append(readBuffer, 0, readBytes);

                this.FireOnDataRead(new String(readBuffer, 0, readBytes));
            }
        }
        catch (ThreadAbortException)
        {
            if (!args.Process.HasExited)
            {
                args.Process.Kill();
            }
        }
    }
}
/// <summary>
/// Represents the ProcessOutputReaderWorkerThreadArguments class.
/// </summary>
public class ProcessOutputReaderWorkerThreadArguments
{
    /// <summary>
    /// Represents the read buffer size,
    /// </summary>
    private int readBufferSize;

    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReaderWorkerThreadArguments"/> class.
    /// </summary>
    /// <param name="process">The process.</param>
    /// <param name="intermediateDataStore">The intermediate data store.</param>
    public ProcessOutputReaderWorkerThreadArguments(Process process, StringBuilder intermediateDataStore)
    {
        this.ReadBufferSize = 128;
        this.Exit = false;
        this.Process = process;
        this.IntermediateDataStore = intermediateDataStore;
    }

    /// <summary>
    /// Gets or sets a value indicating whether the thread shall exit or not.
    /// </summary>
    public bool Exit
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the read buffer size in bytes.
    /// </summary>
    /// <exception cref="System.ArgumentOutOfRangeException">Is thrown if the specified value is not greather than 0.</exception>
    public int ReadBufferSize
    {
        get
        {
            return this.readBufferSize;
        }
        set
        {
            if (value <= 0)
            {
                throw new ArgumentOutOfRangeException("value", "The specified value for \"ReadBufferSize\" must be greater than 0.");
            }

            this.readBufferSize = value;
        }
    }

    /// <summary>
    /// Gets the process.
    /// </summary>
    public Process Process
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the intermediate data store.
    /// </summary>
    public StringBuilder IntermediateDataStore
    {
        get;
        private set;
    }
}
/// <summary>
/// Represents the ProcessOutputReaderEventArgs class.
/// </summary>
public class ProcessOutputReaderEventArgs : EventArgs 
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReaderEventArgs"/> class.
    /// </summary>
    /// <param name="intermediateDataStore">The reference to the intermediate data store.</param>
    /// <param name="newData">The new data that has been read.</param>
    public ProcessOutputReaderEventArgs(StringBuilder intermediateDataStore, string newData)
    {
        this.IntermediateDataStore = intermediateDataStore;
        this.NewData = newData;
    }

    /// <summary>
    /// Gets the reference to the intermediate data store.
    /// </summary>
    public StringBuilder IntermediateDataStore
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the new data that has been read.
    /// </summary>
    public string NewData
    {
        get;
        private set;
    }
}
以及
ProcessOutputReaderEventArgs
类,如下所示:

private void OnDataReadEventHandler(object sender, ProcessOutputReaderEventArgs e)
{
    // e.IntermediateDataStore points to the StringBuilder instance which holds
    // all the data that has been received until now.
    string completeData = e.IntermediateDataStore.ToString();

    // e.NewData points to a string which contains the data that has been received
    // since the last triggered event (because the event is triggered on each read).
    string newData = e.NewData;
}
/// <summary>
/// Represents the ProcessOutputReader class.
/// </summary>
public class ProcessOutputReader
{
    /// <summary>
    /// Represents the instance of the thread arguments class.
    /// </summary>
    private ProcessOutputReaderWorkerThreadArguments threadArguments;

    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReader"/> class.
    /// </summary>
    /// <param name="process">The process which's output shall be read.</param>
    /// <exception cref="System.ArgumentOutOfRangeException">Is thrown if the specified process reference is null.</exception>
    public ProcessOutputReader(Process process)
    {
        if (process == null)
        {
            throw new ArgumentOutOfRangeException("process", "The parameter \"process\" must not be null");
        }

        this.Process = process;
        this.IntermediateDataStore = new StringBuilder();
        this.threadArguments = new ProcessOutputReaderWorkerThreadArguments(this.Process, this.IntermediateDataStore);
    }

    /// <summary>
    /// Is fired whenever data has been read from the process output.
    /// </summary>
    public event EventHandler<ProcessOutputReaderEventArgs> OnDataRead;

    /// <summary>
    /// Gets or sets the worker thread.
    /// </summary>
    private Thread ReaderThread
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the intermediate data store.
    /// </summary>
    private StringBuilder IntermediateDataStore
    {
        get;
        set;
    }

    /// <summary>
    /// Gets the data collected from the process output.
    /// </summary>
    public string Data
    {
        get
        {
            return this.IntermediateDataStore.ToString();
        }
    }

    /// <summary>
    /// Gets the process.
    /// </summary>
    public Process Process
    {
        get;
        private set;
    }

    /// <summary>
    /// Stars reading from the process output.
    /// </summary>
    public void StartReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                return;
            }
        }

        this.ReaderThread = new Thread(new ParameterizedThreadStart(ReaderWorker));
        this.threadArguments.Exit = false;
        this.ReaderThread.Start(this.threadArguments);
    }

    /// <summary>
    /// Stops reading from the process output.
    /// </summary>
    public void StopReading()
    {
        if (this.ReaderThread != null)
        {
            if (this.ReaderThread.IsAlive)
            {
                this.threadArguments.Exit = true;
                this.ReaderThread.Join();
            }
        }
    }

    /// <summary>
    /// Fires the OnDataRead event.
    /// </summary>
    /// <param name="newData">The new data that has been read.</param>
    protected void FireOnDataRead(string newData)
    {
        if (this.OnDataRead != null)
        {
            this.OnDataRead(this, new ProcessOutputReaderEventArgs(this.IntermediateDataStore, newData));
        }
    }

    /// <summary>
    /// Represents the worker method.
    /// </summary>
    /// <param name="data">The thread arguments, must be an instance of the <see cref="ProcessOutputReaderWorkerThreadArguments"/> class.</param>
    private void ReaderWorker(object data)
    {
        ProcessOutputReaderWorkerThreadArguments args;

        try
        {
            args = (ProcessOutputReaderWorkerThreadArguments)data;
        }
        catch
        {
            return;
        }

        try
        {
            char[] readBuffer = new char[args.ReadBufferSize];

            while (!args.Exit)
            {
                if (args.Process == null)
                {
                    return;
                }

                if (args.Process.HasExited)
                {
                    return;
                }

                if (args.Process.StandardOutput.EndOfStream)
                {
                    return;
                }

                int readBytes = this.Process.StandardOutput.Read(readBuffer, 0, readBuffer.Length);
                args.IntermediateDataStore.Append(readBuffer, 0, readBytes);

                this.FireOnDataRead(new String(readBuffer, 0, readBytes));
            }
        }
        catch (ThreadAbortException)
        {
            if (!args.Process.HasExited)
            {
                args.Process.Kill();
            }
        }
    }
}
/// <summary>
/// Represents the ProcessOutputReaderWorkerThreadArguments class.
/// </summary>
public class ProcessOutputReaderWorkerThreadArguments
{
    /// <summary>
    /// Represents the read buffer size,
    /// </summary>
    private int readBufferSize;

    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReaderWorkerThreadArguments"/> class.
    /// </summary>
    /// <param name="process">The process.</param>
    /// <param name="intermediateDataStore">The intermediate data store.</param>
    public ProcessOutputReaderWorkerThreadArguments(Process process, StringBuilder intermediateDataStore)
    {
        this.ReadBufferSize = 128;
        this.Exit = false;
        this.Process = process;
        this.IntermediateDataStore = intermediateDataStore;
    }

    /// <summary>
    /// Gets or sets a value indicating whether the thread shall exit or not.
    /// </summary>
    public bool Exit
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the read buffer size in bytes.
    /// </summary>
    /// <exception cref="System.ArgumentOutOfRangeException">Is thrown if the specified value is not greather than 0.</exception>
    public int ReadBufferSize
    {
        get
        {
            return this.readBufferSize;
        }
        set
        {
            if (value <= 0)
            {
                throw new ArgumentOutOfRangeException("value", "The specified value for \"ReadBufferSize\" must be greater than 0.");
            }

            this.readBufferSize = value;
        }
    }

    /// <summary>
    /// Gets the process.
    /// </summary>
    public Process Process
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the intermediate data store.
    /// </summary>
    public StringBuilder IntermediateDataStore
    {
        get;
        private set;
    }
}
/// <summary>
/// Represents the ProcessOutputReaderEventArgs class.
/// </summary>
public class ProcessOutputReaderEventArgs : EventArgs 
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessOutputReaderEventArgs"/> class.
    /// </summary>
    /// <param name="intermediateDataStore">The reference to the intermediate data store.</param>
    /// <param name="newData">The new data that has been read.</param>
    public ProcessOutputReaderEventArgs(StringBuilder intermediateDataStore, string newData)
    {
        this.IntermediateDataStore = intermediateDataStore;
        this.NewData = newData;
    }

    /// <summary>
    /// Gets the reference to the intermediate data store.
    /// </summary>
    public StringBuilder IntermediateDataStore
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the new data that has been read.
    /// </summary>
    public string NewData
    {
        get;
        private set;
    }
}
//
///表示ProcessOutputReaderEventArgs类。
/// 
公共类ProcessOutputReaderEventArgs:EventArgs
{
/// 
///初始化类的新实例。
/// 
///对中间数据存储的引用。
///已读取的新数据。
public ProcessOutputReaderEventArgs(StringBuilder intermediateDataStore、string newData)
{
this.IntermediateDataStore=IntermediateDataStore;
this.NewData=NewData;
}
/// 
///获取对中间数据存储的引用。
/// 
公共StringBuilder IntermediateDataStore
{
得到;
私人设置;
}
/// 
///获取已读取的新数据。
/// 
公共字符串NewData
{
得到;
私人设置;
}
}

也许您可以使用
ReadLine()
而不是
ReadToEnd()
并在循环中执行该操作。这使您可以在特定时间后退出循环。我如何实现此行的超时,并在超时完成时取消命令提示?我提供了一个小示例(请参见我的答案),不必提及;-)然而,我提供了另一个更“学术化”的解决方案,但在我看来是更好的解决方案(当然要长得多;-)。