Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to block an operation until a condition is met?

Tags:

c#

blocking

I am running this code and it is using a fair amount of CPU even though it is doing absolutely nothing most of the time.

while (this.IsListening)
{
    while (this.RecievedMessageBuffer.Count > 0)
    {
        lock (this.RecievedMessageBuffer)
        {
            this.RecievedMessageBuffer[0].Reconstruct();
            this.RecievedMessageBuffer[0].HandleMessage(messageHandler);
            this.RecievedMessageBuffer.RemoveAt(0);
        }
    }
}

What is the best way to block until a condition is met?

like image 333
MJLaukala Avatar asked Jun 11 '12 05:06

MJLaukala


2 Answers

Use a WaitHandle.

WaitHandle waitHandle = new AutoResetEvent();

// In your thread.
waitHandle.WaitOne();

// In another thread signal that the condition is met.
waitHandle.Set();

You could also consider changing the interface of your class to raise an event when there is new data to be read. Then you can put your code inside the event handler.

like image 140
Mark Byers Avatar answered Nov 14 '22 09:11

Mark Byers


Assuming you are using .NET 4, I'd suggest switching RecievedMessageBuffer to be a BlockingCollection. When you are putting messages into it, call it's Add method. When you want to retrieve a message, call it's Take or TryTake methods. Take will block the reading thread until a message is available, without burning CPU like your original example.

// Somewhere else
BlockingCollection<SomethingLikeAMessage> RecievedMessageBuffer = new BlockingCollection<SomethingLikeAMessage>();


// Something like this where your example was
while (this.IsListening)
{
    SomethingLikeAMessage message;
    if (RecievedMessageBuffer.TryTake(out message, 5000);
    {
        message.Reconstruct();
        message.HandleMessage(messageHandler);
    }
}
like image 29
Chris Shain Avatar answered Nov 14 '22 09:11

Chris Shain