jwcolby
jwcolby at colbyconsulting.com
Wed Apr 4 20:09:56 CDT 2012
Append this to the end of part 1
jwc
#region Methods
/// <summary>InitTimerOrThread
/// Initialize the timer or the thread, depending on which (if either) is being used
/// called from the class constructor
/// </summary>
private void InitTimerOrThread()
{
if (threaded)
{
oThread = new Thread(new ThreadStart(mtStart));
oThread.IsBackground = true;
oThread.Name = rsName;
}
else if (timed)
{
timer = new System.Timers.Timer();
timer.Interval = pTimerInterval; //Timer fires every N milli-seconds
//timer.
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
}
/// <summary>mStart
/// Call this method to tell the parent of this class to start processing
/// and clear the stop flag
///
/// Only called by the object asking the parent to start
/// </summary>
public void mStart()
{
switch (runState)
{
case RunState.Started:
//
//If the application is Running then do nothing
break;
case RunState.Starting:
//If the application is Starting then do nothing
break;
case RunState.Stopped:
//
//If the application is in the stopped state, then do a start
mDoTheStart();
break;
case RunState.Stopping:
//
//The application must call the mStopped event which will set the RunState
to Stopped.
//and break out of this loop.
while (runState == RunState.Stopping) { Application.DoEvents(); }
//
//When the application finishes stopping,
mDoTheStart();
break;
}
}
/// <summary>mStarting
/// Called by the parent to indicate that we are starting
/// (not stopped)
/// but not started yet.
///
/// If the parent uses this state it MUST call the started method
/// or the stop will never process and the system WILL HANG
///
/// The Starting and Stopping states allow a little finer granularity
/// to the status of the parent process.
/// </summary>
public void mStarting()
{
runState = RunState.Starting;
}
/// <summary>mStarted
/// The parent (application) must call this method to change the runstate to started
///
/// !!!Failure to do so will hang the system!!!
///
/// </summary>
public void mStarted()
{
//
//Tell the user that we have started
invokeChkBox(startedCol, startedText, true);
invokeBtn(startedCol, stopText + " " + rsName, true); //For the button we
want to end up with the word "Stop" in the text when it is able to stop the process.
//
//And set the runstate to started
runState = RunState.Started;
}
/// <summary>mDoTheStart
/// Updates the checkbox label (if any)
/// Sets the RunState to Starting
///
/// and raises the start event or
/// starts a thread which raises the start event or
/// starts a timer which will periodically call its event
/// </summary>
private void mDoTheStart()
{
invokeChkBox(startingCol, startingText, true); //Tell the user we are starting
invokeBtn(startingCol, startingText + " " + rsName, true); //Disable the button
runState = RunState.Starting; //Set the RunState to Starting
if (threaded)
{
oThread.Start(); //Using a thread so call the delegate (mtStart)
}
else if (timed)
{
evStart(this); //Do the preliminary stuff that has to occur before the
timer tick. Some stuff only has to happen once.
timer.Start(); //Using a timer so start the timer. This will periodically
call the timer's delegate
}
else
{
evStart(this); //Not threaded in any way so just do it directly
}
}
/// <summary>mStop
/// Call this method to tell the parent of this class to stop processing
/// and set the stop flag
///
/// Only called by the object asking the parent to stop
/// </summary>
public void mStop()
{
switch (runState)
{
case RunState.Started:
//
//The application must be fully up and running
mDoTheStop();
break;
case RunState.Starting:
//
//We can't stop in the middle of starting since we will be in an unknown state
//
//The application must call the mStarted event which will set the RunState
to Started
//and break out of this loop.
while (runState == RunState.Starting) { Application.DoEvents(); }
//
//Once the application is Started then
mDoTheStop();
break;
case RunState.Stopped:
//The RunState is already stopped so do nothing
break;
case RunState.Stopping:
//
//We can't stop (again) in the middle of stopping since we will be in an
unknown state
//
//The application must call the mStopped event which will set the RunState
to Stopped.
//and break out of this loop.
while (runState == RunState.Stopping)
{
Application.DoEvents();
}
break;
}
}
/// <summary>mStopping
/// Called by the parent to indicate that we are stopping
/// (no longer running)
/// but not stopped yet
///
/// If the parent uses this state it MUST call the started method
/// or the stop will never process and the system WILL HANG
///
/// The Starting and Stopping states allow a little finer granularity
/// to the status of the parent process.
///
/// It allows us to say "yes I know I am supposed to stop but I am not finished and
can't just shut down right now"
/// </summary>
public void mStopping()
{
runState = RunState.Stopping;
}
/// <summary>mStopped
/// The parent must call this method to change the runstate to stopped
///
/// !!!Failure to do so will hang the system!!!
///
/// </summary>
public void mStopped()
{
try
{
//Tell the user we have stopped
invokeChkBox(stoppedCol, stoppedText, true);
//
//And set the runstate to stopped
runState = RunState.Stopped;
}
catch (Exception ex)
{
}
}
/// <summary>mDoTheStop
/// Updates the checkbox label (if any)
/// Sets the RunState to Stopping
/// and raises the stop event
/// </summary>
private void mDoTheStop()
{
invokeChkBox(stoppingCol, stoppingText, true); //Tell the user we are stopping
runState = RunState.Stopping; //Set the RunState to Stopping
if (timed)
{
timer.Stop(); //Using a timer so stop the timer. This will periodically
call the timer's delegate
}
evStop(this); //And call the Stop Event
invokeBtn(stoppingCol, startText + " " + rsName, true); //Enable the button
}
#endregion
#region Dispose
private bool disposed = false; //Track whether Dispose has been called.
~clsRunState()
{
Dispose(true);
}
public void Close()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
oThread = null;
timer = null;
}
}
disposed = true;
}
#endregion
}
}
--
John W. Colby
Colby Consulting
Reality is what refuses to go away
when you do not believe in it