June 4, 2006

Thread Pattern Starter Class

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: