Background thread class as a starter for a threading class.
class WorkerThread
{
public WorkerThread()
{
StartThread();
}
~WorkerThread()
{
Dispose(false);
}
#region IDisposable Members
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
// Dispose managed resources
}
// Dispose unmanaged resources
EndThread();
}
m_disposed = true;
}
#endregion
#region Private Threading Related
/// <summary>
/// Actual threa object
/// </summary>
private Thread m_Thread = null;
/// <summary>
/// Give the thread a meaningful threadId
/// </summary>
private string threadId = "MyThreadName";
/// <summary>
/// Time to wait for the thread to finish
/// when merging the thread
/// back to the main thread
/// </summary>
private uint waitForEndThread = 5000; // 5 seconds
/// <summary>
/// How long to pause for at the end of each iteration
/// </summary>
private int m_ThreadSleepPeriod = 200;
/// <summary>
/// We use the m_PauseEvent to control the sleep period
/// of the thread. The m_PauseEvent
/// sleeps for the given period but we can force it to
/// wake up early by calling
/// Set on it.
/// </summary>
private AutoResetEvent m_PauseEvent = new AutoResetEvent(false);
/// <summary>
/// This does not need special protected access.
/// It is set to false before the thread is
/// started and can only get set to true when
/// the thread thread has begun.
/// </summary>
private bool m_Stop = false;
/// <summary>
/// Start the thread running
/// </summary>
private void StartThread()
{
if (m_Thread != null)
{
EndThread();
}
if (m_Thread == null)
{
if (m_PauseEvent == null)
{
m_PauseEvent = new AutoResetEvent(false);
}
m_Stop = false;
m_Thread = new Thread(new ThreadStart(
this.ThreadRoutine));
m_Thread.IsBackground = true;
m_Thread.Start();
m_Thread.Name = threadId;
Thread.Sleep(0);
}
}
/// <summary>
/// EndThread to the thread to terminate it
/// </summary>
private void EndThread()
{
m_Stop = true;
if (m_Thread != null)
{
if (m_PauseEvent != null)
{
m_PauseEvent.Set();
}
try
{
if (m_Thread.IsAlive)
{
System.Diagnostics.Debug.WriteLine(
"WorkerThread.EndThread(): EndThreading this thread \'"+
m_Thread.Name + "\' to \'" + Thread.CurrentThread.Name + "\'");
// Wait X seconds for the thread to finish
if (!m_Thread.Join((int)waitForEndThread))
{
System.Diagnostics.Debug.WriteLine(
"WorkerThread.EndThread(): EndThread() failed, so ABORTing thread\'" +
m_Thread.Name + "\'");
m_Thread.Abort(); // otherwise abort
}
else
{
System.Diagnostics.Debug.WriteLine(
"WorkerThread.EndThread(): EndThread() succeeded, Thread \'"+
m_Thread.Name + "\' is terminated");
}
}
else
{
System.Diagnostics.Debug.WriteLine(
"WorkerThread.EndThread(): Thread \'" +
m_Thread.Name + "\' is not 'Alive' so EndThread() not invoked");
}
}
catch (System.Threading.ThreadStateException ex)
{
// Swallow any ThreadStateExceptions
System.Diagnostics.Debug.WriteLine(
"WorkerThread.EndThread(): ThreadStateException caught in thread \'" +
m_Thread.Name + "\'" + ex.ToString());
}
m_Thread = null;
if (m_PauseEvent != null)
{
m_PauseEvent.Close();
m_PauseEvent = null;
}
}
}
/// <summary>
/// The routine executed within the new thread
/// </summary>
private void ThreadRoutine()
{
string thrdName = m_Thread.Name;
System.Diagnostics.Debug.WriteLine("Thread \'" +
thrdName + "\' thread routine is started");
try
{
while (m_Stop != true)
{
ThreadWork();
if ((m_Stop != true) &&
(m_ThreadSleepPeriod >= 0))
{
m_PauseEvent.WaitOne(m_ThreadSleepPeriod,
false);
}
}
}
catch (Exception ex)
{
m_Stop = true;
//if (log != null)
System.Diagnostics.Debug.WriteLine(
"FATAL exception caught in thread routine \'" +
thrdName.ToString() + "\' Thread will be terminated" + ex.ToString());
}
System.Diagnostics.Debug.WriteLine("Thread \'" + thrdName +
"\' end of thread routine reached");
}
private void ThreadWork()
{
// Do something
}
#endregion
}
No comments:
Post a Comment