views:

102

answers:

4

Hello,

I've been working on a thread which will live aslong as the application is running, and runs at a interval of 500ms. I noted that i could be uselessly processing if there's nothing in the queue for it to process, so i went around looking at some sources i had locally, and i found an example close to mine, but it's in Java.

The example had this:

synchronized(this) {
    try {
        wait();
    } catch (InterruptedException e) {
        cleanup();
        break;
    }
}

Inside a while loop which goes on forever.

The thread has this to notify the wait:

synchronized(this) {
    notifyAll();
}

This was inside the enqueue thread. I'd also like you to note that the class inherits Runnable.

Could anyone quickly explain the corresponding functions in C#? And maybe an example if you could!

Thanks in advanced, AJ Ravindiran.

+4  A: 

.NET/C# best practice would be to use an EventWaitHandle.

You'd have some variable shared between the threads as so:

EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);

In the consumer thread (the one that you're waking up every 500ms right now), you'd loop waiting for the handle (perhaps with a timeout):

try
{
    while(true)
    {
        handle.WaitOne();
        doSomething();
    }
}
catch(ThreadAbortException)
{
    cleanup();
}

And in the producer thread:

produceSomething();
handle.Set();
Robert Fraser
+1  A: 

Maybe you can use a blocking queue : http://www.eggheadcafe.com/articles/20060414.asp

It's a Queue except Dequeue function blocks until there is an object to return.

Usage:

BlockingQueue q = new BlockingQueue();

  void ProducerThread()
  {
    while (!done)
      {
        MyData d = GetData();
        q.Enqueue(d);
        Thread.Sleep(100);
     }
  }

  void ConsumerThread()
  {
    while (!done)
      {
        MyData d = (MyData)q.Dequeue();
        process(d);
      }
  }

The consumer thread only executes when there is something in the queue to process, and doesn’t waste CPU time polling when there is nothing to do.

Catalin DICU
A: 

Use a timer that fires every 500ms and let your timer handler do the work. Timer handler threads run in the thread pool. Read about it here: http://www.albahari.com/threading/part3.aspx#_Timers.

System.Timers.Timer timer = new System.Timer(500);
timer.Elapsed += new System.Timers.ElapsedEventHandler (MyTimerHandler);
timer.Start();

private void TimerHandler(object sender, System.Timers.ElapsedEventArgs e)
{
    // optional - stop the timer to prevent overlapping events
    timer.Stop();
    // this is where you do your thing
    timer.Start();
}
ebpower
For a timer that will continue to run for the entire duration of the process then using a `System.Threading.Timer` would be be a slightly more performant/efficient option.
STW
@Yooder, not sure if it would be significantly more performant, but it would be much simpler to use.
gWiz
Per the referenced Alahari paper: "... the System.Timers namespace. This simply wraps System.Threading.Timer, providing additional convenience while using the same thread pool ...". Why would there be a performance difference?
ebpower
A: 

You might want to download and read Joe Albahari's free ebook on threading in C#. It's a great introduction and reference.

Threading in C#

Winston Smith