In my last post I showed you how to create a process that will read from the Twitter firehose and post to an MSMQ queue, where another process can read from it and process a database. Well that’s fine in and of itself, but there is a slight wrinkle in as much as that process will stop from time to time for various reasons – Twitter even give a list of things that will cause them to close the connection from their end, thus stopping the process. Now if you are planning to sit around all day just watching that process then that’s fine but, if like me, you have better things to do with your time, then you really need a small application to watch over the process and restart it if it stops. That’s what we are going to look today.
So, let’s create a little GUI app with two buttons, one to start the process and one to end it – we’ll include the DX gauge as well, so we can instantly see the state of our process. The form will look like this:
As you can see, there’s a little sad face to indicate that the process is not currently running.
The first thing we have to do now is to define an enum so that we can hide the “magic numbers” for the stateIndex on the gauge:
public enum State
{
Started = 0,
Starting = 2,
Stopped = 4
}
We’ll also need a backing store for a restart flag and the process that we are watching:
//GS - Create a flag to show if we want to restart on process stop
private bool restartFlag = true;
//GS - Backing store for our process
private Process process = null;
Now when the “Start Process” button is pressed, we want to run the following code:
private void button1_Click(object sender, EventArgs e)
{
//GS - Start the process on anther thread so the GIU stays responsive
ThreadPool.QueueUserWorkItem(StartProc);
}
Which will start the process thus:
private void StartProc(object stateInfo)
{
//GS - If we are not starting/restarting then we're done
if (!restartFlag)
return;
//GS - If we've already got a process just restart it
if (process != null)
{
process.Start();
ThreadPool.QueueUserWorkItem(WatchProcess);
return;
}
//GS - Create a process to start Powershell
stateIndicatorComponent1.StateIndex = (int)State.Starting;
ProcessStartInfo si = new ProcessStartInfo();
si.UseShellExecute = false;
si.FileName = "powershell";
Process p = new Process();
p.StartInfo = si;
process = p;
//GS - Update the indicator to show the process has started
stateIndicatorComponent1.StateIndex = (int)State.Started;
//GS - Start the process
process.Start();
//GS - Monitor the process on a seperate thread
ThreadPool.QueueUserWorkItem(WatchProcess);
}
Here, as you an see, we are starting an instance of Powershell, just for an example. This code is well commented and is very similar to that shown in the last post so we wont say anymore about it. As you can see though, once the process is started another thread is spun off to watch the process:
private void WatchProcess(object stateInfo)
{
//GS - If there is no process to watch then we're done
if (process == null)
return;
//GS - When the process exits...
while (!process.HasExited) { };
//GS - Check if I'm supposed to restart it..
if (restartFlag)
//GS - If so, start it.
ThreadPool.QueueUserWorkItem(StartProc);
}
As you can see, the watcher does nothing whilst the process is running, but once it has excited it checks to see if the restart flag is set to true, and if it is then the process is restarted:
And our watcher application shows a smiley face to indicate that the process is running:
Of course at some point we are going to want to stop the process and not have it immediately restart. When the “Stop Process” button is pressed, the following code will achieve that:
private void button2_Click(object sender, EventArgs e)
{
//GS - Set the flag so that we don't restart the process
restartFlag = false;
//GS - Stop the process and indicate that it's stopped
process.Kill();
stateIndicatorComponent1.StateIndex = (int)State.Stopped;
}
And there you have it, a small application to monitor your processes and have the automatically restart when they stop. Until next time, happy coding! :-)