为什么重新启动进程时不再收到OutputDataReceived事件? - c#

我有一个ChildProcessMonitor类,该类可启动进程,报告收到的数据并在退出时重新启动进程。我的问题是,一旦进程退出并再次调用Start,就不再报告输出。

using System;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace WcfClient
{
    /// <summary>
    /// Can be used to launch and monitor (restart on crash) the child process.
    /// </summary>
    public class ChildProcessMonitor
    {
        private Process _process;

        /// <summary>
        /// Starts and monitors the child process.
        /// </summary>
        /// <param name="fullProcessPath">The full executable process path.</param>
        public void StartAndMonitor(string fullProcessPath)
        {
            StartAndMonitor(fullProcessPath, null);
        }

        /// <summary>
        /// Starts and monitors the child process.
        /// </summary>
        /// <param name="fullProcessPath">The full executable process path.</param>
        /// <param name="arguments">The process arguments.</param>
        public void StartAndMonitor(string fullProcessPath, string arguments)
        {
            ProcessStartInfo processStartInfo = new ProcessStartInfo
            {
                CreateNoWindow = true,
                FileName = fullProcessPath,
                WorkingDirectory = Path.GetDirectoryName(fullProcessPath) ?? string.Empty,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };

            processStartInfo.Arguments = arguments;             

            _process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true };
            _process.OutputDataReceived += OnOutputDataReceived;
            _process.ErrorDataReceived += OnErrorDataReceived;
            _process.Start();
            _process.BeginOutputReadLine();
            _process.BeginErrorReadLine();
            _process.Exited += OnProcessExited;
        }

        /// <summary>
        /// Called when process exits.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OnProcessExited(object sender, EventArgs e)
        {
            if (_process != null)
            {
                Thread.Sleep(2000);                 
                _process.Start();                       
            }
        }

        /// <summary>
        /// The ErrorDataReceived event indicates that the associated process has written to its redirected StandardError stream.
        /// </summary>
        public DataReceivedEventHandler ErrorDataReceived;

        /// <summary>
        /// Called when error data received.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Diagnostics.DataReceivedEventArgs"/> instance containing the event data.</param>
        private void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            Trace.WriteLine("Error data.");
            if (ErrorDataReceived != null)
            {
                ErrorDataReceived(sender, e);
            }
        }

        /// <summary>
        /// The OutputDataReceived event indicates that the associated Process has written to its redirected StandardOutput stream.
        /// </summary>
        public DataReceivedEventHandler OutputDataReceived;

        /// <summary>
        /// Called when output data received.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Diagnostics.DataReceivedEventArgs"/> instance containing the event data.</param>
        private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            Trace.WriteLine("Output data.");
            if (OutputDataReceived != null)
            {
                OutputDataReceived(sender, e);
            }
        }

    }

}

参考方案

尝试使用:

private void OnProcessExited(object sender, EventArgs e)
{
  if (_process != null)
  {
    Thread.Sleep(2000);
    _process.CancelOutputRead();
    _process.CancelErrorRead();
    _process.Start();
    _process.BeginOutputReadLine();
    _process.BeginErrorReadLine();

  }
}

ps

简短说明:OutputRead和ErrorRead在进程重新启动后关闭。

带有反射代码的详细描述:

public void BeginOutputRead()
{
  [..]
  if (this.output == null)
  {
    [..]                    
    this.output = new AsyncStreamReader(this, baseStream, new UserCallBack(this.OutputReadNotifyUser), this.standardOutput.CurrentEncoding);
  }
}

public void Start()
{   
    this.Close();
    [..]
}

public void Close()
{   
    [..]
    this.output = null;
    this.error = null;
    [..]
}

jQuery不起作用 - php

我正在使用带有ajax的jquery。有时,给出错误$未定义。这是我的代码:<script language="javascript" type="text/javascript"> var base_path="<? echo $this->baseUrl().'/…

Div单击与单选按钮相同吗? - php

有没有一种方法可以使div上的click事件与表单环境中的单选按钮相同?我只希望下面的div提交值,单选按钮很丑代码输出如下:<input id="radio-2011-06-08" value="2011-06-08" type="radio" name="radio_date&#…

故障排除“警告:session_start():无法发送会话高速缓存限制器-标头已发送” - php

我收到警告:session_start()[function.session-start]:无法发送会话缓存限制器-标头已发送(错误输出开始如果我将表单数据提交到其他文件进行处理,则可以正常工作。但是,如果我将表单数据提交到同一页面,则会出现此错误。请建议<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0…

无法解析Json响应 - php

我正在尝试解析一个包含产品类别的JSON文件,然后解析这些类别中的产品,并在div中显示它们。我的问题:虽然我可以获取类别,但我不知道如何索取产品(并将它们显示在类别下)。我的剧本:<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> …

<T>如何在这里处理String和Integer - java

我不明白T如何使用Integer和String。如此处显示功能中所示,T同时处理整数和字符串。该代码如何工作?class firstBase { <T> void display(T give_num, T give_String) { System.out.println("The given number is = " +…