How to block an operation until a condition is met?

I run this code and it uses enough CPU, even if it doesn’t do anything in most cases.

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?

+6
source share
3 answers

Assuming you are using .NET 4, I suggest switching RecievedMessageBuffer to BlockingCollection . When you insert messages into it, name it Add Method. When you want to receive a message, call it the Take or TryTake methods. Take will block the read stream until the message is available, without writing to the processor, as 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); } } 
+7
source

Use WaitHandle .

 WaitHandle waitHandle = new AutoResetEvent(); // In your thread. waitHandle.WaitOne(); // In another thread signal that the condition is met. waitHandle.Set(); 

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

+9
source

Above the lines of code and, in particular, AutoResetEvent is available in version 3.5. So a simple code like the one above with some minor correction is very efficient because it works and comes close to the base API. Correction should be

AutoResetEvent waitHandle = new AutoResetEvent (false); A constructor with an argument of false causes WaitOne () to wait because AutoResetEven is not reset (false). There are not many advantages to using the WaitHandle interface, so I would just use AutoResetEvent since it provides the Set and WaitOne method in this case is pretty verbose. Most importantly, the constructor argument must be false.

+2
source

Source: https://habr.com/ru/post/917753/


All Articles