Does WaitHandle.WaitOne() include time hibernated/sleeping?

Viewed 46

In .NET, does WaitHandle.WaitOne(int millisecondsTimeout) (and presumably methods that block with timeouts, such as Thread.Sleep()) include time that the computer is hibernating or sleeping? For example, if I call WaitHandle.WaitOne(600000) to timeout in ten minutes, the computer hibernates for 5 of those minutes, will it timeout 10 minutes after calling or 15 minutes after calling?

My goal is to have it not include time spent during hibernation or sleeping.

1 Answers

Since Windows 7, kernel32.dll has a QueryUnbiasedInterruptTime function.

The unbiased interrupt-time count does not include time the system spends in sleep or hibernation.

The remarks provide pretty conclusive evidence that ordinary waits and timers do count time spent suspended:

The interrupt-time count retrieved by the QueryUnbiasedInterruptTime function reflects only the time that the system is in the working state. Therefore, the interrupt-time count is not "biased" by time the system spends in sleep or hibernation. The system uses biased interrupt time for some operations, such as ensuring that relative timers that would have expired during sleep expire immediately upon waking.

You will probably need p/invoke to call it from C# since I've never heard of any .NET base class library approach to doing it.

It doesn't put your thread to sleep by itself, you'll have to call it before and after the synchronizing sleep and calculate how much sleep time you still need (in case you lost some due to power savings) and then return to sleep again with the new timeout. Repeat in a loop until you actually sleep for as much CPU time as desired.

If you're using async code, there's no reason you couldn't use this function also for recalibration of Task.Delay, which you call in a loop. CancellationTokenSource.CancelAfter is a bit more problematic, since you can't uncancel if your calculation reveals you need to adjust the timeout. So you'd have to separately sleep and cancel the token yourself, without the help of scheduled cancellation.


Finally, if you're trying to set a timeout to happen after some other process has had a chance to do a certain amount of work, regardless of the passage of wall-clock time, you should be using resource limits on a Job object. The Job object measures CPU time actually spent by a particular process and is unaffected by time the process isn't working, whether due to suspend, being preempted by higher priority tasks, etc.

Related