开发者

.NET - Thread synchronization

开发者 https://www.devze.com 2022-12-16 21:07 出处:网络
I\'ve been working on a thread which will live as long 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

I've been working on a thread which will live as long 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!


.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();


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.


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();
}


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#

0

精彩评论

暂无评论...
验证码 换一张
取 消