0

ManualResetEvent basically says to other threads "you can only proceed when you receive a signal to continue" and is used to pause execution for certain threads until certain condition has been fulfilled. What I want to ask is that why ManualResetEvent when we could easily achieve what we want by using a while loop? Consider the following context:

public class BackgroundService {

ManualResetEvent mre;
public BackgroundService() {
    mre = new ManualResetEvent(false);
}
public void Initialize() {
    // Initialization
    mre.Set();
}

public void Start() {
    mre.WaitOne();
    // The rest of execution
}
}

is somewhat similar to

public class BackgroundService {

bool hasInitialized;
public BackgroundService() {

}
public void Initialize() {
    // Initialization
    hasInitialized = true;
}

public void Start() {
    while (!hasInitialized)
    Thread.Sleep(100);
    // The rest of execution
}
}

Is there any particular context where ManualResetEvent is more suitable than a while loop?

user1928346
  • 513
  • 6
  • 21
  • 1
    `ManualResetEvent` is more accurate. Your loop can lose 99ms for nothing in worst case. – Sinatr Dec 09 '13 at 06:53
  • The thread will be the same in the while loop in that it wouldn't be able to do any other work really where as if you had multiple threads, there could be certain areas that may need some indication to continue doing the next thing the thread does, for example, could be batching of results where T1 batches them, raises a signal, then T2 could be perhaps doing a batch insert/processing of the batch. This is just an example - each thread would be dedicated to doing something. a single thread wouldn't so much and can be slow in perf and maintainability – Ahmed ilyas Dec 09 '13 at 06:53
  • How do you achieve things like thread synchronization with while loop? It's simple and straight forward with manualresetevent. You need to also consider what construct suit your need from design perspective i think. – Sameer Dec 09 '13 at 07:13

2 Answers2

3

Is there any particular context where ManualResetEvent is more suitable than a while loop?

Absolutely. There are two primary reasons: latency and efficiency.

Context-switching the thread to start it running again is relatively expensive, when it's just going to go back to sleep, and the approach you've given will take an average of 50ms to respond to the hasInitialized variable being set - assuming it responds at all. (You don't have any explicit memory barriers, so it's possible that the thread won't actually see a change to the variable at all. I suspect that calling Thread.Sleep effectively adds a memory barrier, but it's not guaranteed.) With OS/CLR-level synchronization primitives, a thread can respond much faster.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

Using signals such as that provided ManualResetEvent is more efficient. Using a while loop as you have means after roughly every 100 milliseconds, i.e. 10 times a second, other threads have to stop running so your thread to check the condition has to run, this context switch when the condition is mostly false is less efficient.

However something smells very fishy in your code, why would you have such code polling when something is initialized? If the initialisation is asynchronous there will already be some notification mechanism, e.g. a callback, when it is done so the polling is unnecessary.

markmnl
  • 11,116
  • 8
  • 73
  • 109