启动进程然后引发事件以监视它们

时间:2012-01-27 19:28:51

标签: c# process timer

我正在启动一个运行外部第三方软件包的进程。然后,我想启动一个计时器,每隔几秒触发一次事件,以监视此进程的输出。这是我用来启动过程的代码:

Process process = new Process();
process.StartInfo.FileName = exe;
process.StartInfo.Arguments = args;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.BeginErrorReadLine();
RuntimeMonitor rtm = new RuntimeMonitor(OutputFile(), InputFile(), 5000);
process.WaitForExit();
rtm.Close();

运行时监视器的构造函数是:

public RuntimeMonitor(string _outfile,
                      string _title,
                      double intervalMs) // in milliseconds
{
    outFile = outfile;
    title = _title;
    timer = new System.Timers.Timer();
    timer.Interval = intervalMs;
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_func);
    timer.AutoReset = true;
    timer.SynchronizingObject = null;
    timer.Start();
}

我得到的症状是在进程结束之前(即在process.WaitForExit();完成之后)才调用timer_func。我以为计时器已过时事件是异步触发的,但它似乎被锁定了

编辑:好吧,它变得陌生。我确实尝试将timer.SynchronizingObject设置为null,但无济于事。我也尝试使用System.Threading.Timer类并得到相同的结果。

还有一条信息。我发出一个调用来开始从进程中收集数据,但不确定它是否相关(即上面代码中的BeginErrorReadLine调用)

2 个答案:

答案 0 :(得分:2)

我不确定为什么你的计时器似乎没有开火。我拿了你的代码并对其进行了一些设计,试图对其进行测试。以下代码工作得很好。也许你可以用它来让你的工作。

void Main()
{
    Process process = new Process();
    process.StartInfo.FileName = "notepad.exe";
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;
    process.Start();
    RuntimeMonitor rtm = new RuntimeMonitor(5000);
    process.WaitForExit();
    rtm.Close();
}

public class RuntimeMonitor
{
    System.Timers.Timer timer;

    // Define other methods and classes here
    public RuntimeMonitor(double intervalMs) // in milliseconds
    {
        timer = new System.Timers.Timer();
        timer.Interval = intervalMs;
        timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_func);
        timer.AutoReset = true;
        timer.Start();
    }

    void timer_func(object source, object e)
    {
        Console.WriteLine("Yes");
    }

    public void Close()
    {
        timer.Stop();
    }
}

答案 1 :(得分:0)

我知道你的代码显示你在RuntimeMonitor构造函数中创建了计时器,但为了以防万一 - 检查你的Timer的Timer.SynchronizingObject属性并确保它为null。如果不是,那么这可以解释你的情况。注意在设计器中使用Timer也会设置属性 - 来自MSDN:

  

如果在Windows窗体设计器中的Visual Studio中使用Timer,则SynchronizingObject会自动设置为包含Timer的控件。例如,如果将Timer放置在Form1的设计器上(继承自Form),则Timer的SynchronizingObject属性将设置为Form1的实例。