.NET - Thread synchronization
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#
精彩评论