Reputation:
I am starting a process that runs an external 3rd party package. I would then like to start a timer that fires an event every few seconds to monitor the output of this process. Here's the code I use to start the process:
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();
The constructor for the runtime monitor is:
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();
}
The symptom I am getting is that timer_func is not called until the process ends (i.e. after process.WaitForExit(); completes). I thought the timer elapsed event fired asynchronously, but it seems to be locked
EDIT: well it gets stranger. I did try setting timer.SynchronizingObject to null, but to no avail. I also tried using the System.Threading.Timer class and got the same result.
One more piece of information. I do issue a call to start gathering data from the process, but not sure that is relevant (i.e. the BeginErrorReadLine call in the code above)
Upvotes: 3
Views: 1482
Reputation: 12493
I know your code shows that you create the timer inside the RuntimeMonitor constructor, but just in case - check the Timer.SynchronizingObject property of your Timer and make sure it is null. If it is not, then that might explain your situation. Note using the Timer in the designer will set the property as well - From MSDN:
If the Timer is used inside Visual Studio in a Windows Forms designer, SynchronizingObject is automatically set to the control that contains the Timer. For example, if you place a Timer on a designer for Form1 (which inherits from Form), the SynchronizingObject property of Timer is set to the instance of Form1.
Upvotes: 0
Reputation: 1863
I am not sure why your timer does not appear to be firing. I took your code and structured it a bit to try and test this out. The following code works just fine. Perhaps you can use it to get your's working.
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();
}
}
Upvotes: 2