Synchronous event threads

C# supports what I call waitForEvent threads or formally known as synchronous event threads.  This is a thread that is fired whenever an event in another thread occurs.  I use this type of thread to perform an action when a bit transitions from true to false, a variable transitions above/below a limit.  The reason for doing this is because we do not want to interrupt the timer thread which checks these values on a 1-sec basis with the chore of building & sending messages, updating database tables, etc.

The design of L1 Monitor is to allow the timer thread to strictly check any transitions in bits or integers .    Initially, the threads are created and then wait until its event is set from another thread.

There are two types of synchronous  event thread: ManualResetEvent and AutoResetEvent.  I make use of the AutoResetEvent since the timer thread cannot waitupon a worker thread from completing its task.

Later, you will see how the worker thread is not fired by the timer when it is still running.

The worker thread has two states: signaled & reset.    Initially, the worker thread enters the reset state.  It wait for the event by making a call to WaitOne(). A signal state is set by the calling thread when issuing a call to Set().  When the thread is initiated, it waits for the event .  When the signal state is Set, the call to WaitOne() returns and the worker thread resumes execution.  Since I am using the AutoResetEvent worker thread, it automatically enters a reset state upon event notification.

Since parameters are not passed into  the worker thread (because it waiting for the event), we make use of static volatile variables to pass variables between the calling thread and the worker thread.   Static makes the variable global while volatile indicates that a field might be modified by multiple threads.

Here is an example on using a worker thread (comments explain what is happening…)

First, define the synchronous events using EventWaitHandle.  Initialize the event as non-signaled or reset state.


/* Define the sync event.  Specify the constructor with false to 
    indicate the thread will be created whose state is initialized 
    as reset */

static EventWaitHandle Level1Tbl = new AutoResetEvent(false);

Define the variables that are shared with the worker threads:

static volatile int iActivePOR;
static volatile int iHeadCropFtg;

/* This flag is set when the worker thread is running.  
    The calling thread checks this flag before signaling the 
    event to make sure that the worker event is not signaled 
    when it is already running */

static volatile bool boLevel1TblWorking = false;

In the service’s OnStart event, define and start the worker thread. Since the thread is created whose state is reset, the threads wait until needed.


/* Create worker thread and start it */
new Thread(HeadCropWorker).Start(); 

Create the worker thread as a function in the same class as the calling thread:

static void HeadCropWorker()
{
    StringBuilder sb = new StringBuilder();
    evtCropFtgThrd.WriteEntry("Head crop thread starting...", 
                    EventLogEntryType.Information);
    while (true)
    {
        string sActiveCoilNbr;

        /* Wait here until the event is signaled */
        HeadCropEvt.WaitOne();
        
        /* Set the flag to indicate that the thread is running */
        boHeadCropWorking = true;  

        if (iActivePOR == 1)
             sActiveCoilNbr = sCoilNbrAtPOR1;
         else
             sActiveCoilNbr = sCoilNbrAtPOR2;
         sb.Length = 0;
         sb.Append("Head crop received for coil ").Append(sActiveCoilNbr);
         sb.Append(" Active POR: ").Append(iActivePOR.ToString());
         sb.Append(" head crop ftg: ").Append(iHeadCropFtg.ToString());

         evtCropFtgThrd.WriteEntry(sb.ToString(), EventLogEntryType.Information);

         /* Thread is finished; ready for next event signal */
         boHeadCropWorking = false;
     }
}

The calling thread calls the worker thread:


     iActivePOR = (arByteEntry[clsGlobalDefs.POR1_ACTIVE_ON] == 1 ? 1 : 2);
     iHeadCropFtg = arIntEntry[clsGlobalDefs.ENTRY_HD_CROP_FTG];
     if (!boHeadCropWorking)
     {
         /* Set the event state to fire off the worker thread */
         HeadCropEvt.Set();           
     }
     else
         evt.WriteEntry("Head Crop Ftg worker still running...", EventLogEntryType.Warning);

Advertisements

One Response to Synchronous event threads

  1. TumGlumeTyday says:

    6 мар 2007 Что такое диета для домохозяйки и с чем ее едят?, Диета для домохозяйки, Диеты, Красота и здоровье, женский журнал, красота, здоровье, дети,
    Все диеты мира. Каталог диет. Похудение. Энциклопедия здоровья.
    Именно эти продукты и стали основными составляющими китайской диеты. Тремя главными правилами диеты являются: строгое соблюдение последовательности
    28 май 2011 Сайт для девушек и женщин. Статьи о фитнесе, здоровом питание, эффективных диетах. Диеты для похудения, как быстро похудеть,
    На сегодняшний день существует множество различных диет, среди этого многообразия можно найти и такую, которая подойдет истинным кофеманам.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: