No, this is fundamentally broken code. There are only reasonable odds that the WaitOne() will complete when you keep the MRE set for such a short amount of time. Windows favors releasing a thread that's blocked on an event. But this will drastically fail when the thread isn't waiting. Or the scheduler picks another thread instead, one that runs with a higher priority and also got unblocked. Could be a kernel thread for example. MRE doesn't keep a "memory" of having been signaled and not yet waited on.
Neither Sleep(0) or Sleep(1) are good enough to guarantee that the wait is going to complete, there's no reasonable upper bound on how often the waiting thread could be bypassed by the scheduler. Although you probably ought to shut down the program when it takes longer than 10 seconds ;)
You'll need to do this differently. A simple way is to rely on the worker to eventually set the event. So reset it before you start waiting:
private static void PeriodicWait() {
Stopwatch stopwatch = new Stopwatch();
while (true) {
stopwatch.Restart();
_handle.Reset();
bool result = _handle.WaitOne(5000);
stopwatch.Stop();
Console.WriteLine("After WaitOne: {0}. Waited for {1}ms", result ? "success" : "failure",
stopwatch.ElapsedMilliseconds);
}
}
private static void PeriodicSignal() {
while (true) {
_handle.Set();
Thread.Sleep(800); // Simulate work
}
}