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.