我正在启动一个运行外部第三方软件包的进程。然后,我想启动一个计时器,每隔几秒触发一次事件,以监视此进程的输出。这是我用来启动过程的代码:
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调用)
答案 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的实例。