TimerQueue.Windows.cs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Diagnostics;
  5. namespace System.Threading
  6. {
  7. internal partial class TimerQueue
  8. {
  9. private static long TickCount64
  10. {
  11. get
  12. {
  13. // We need to keep our notion of time synchronized with the calls to SleepEx that drive
  14. // the underlying native timer. In Win8, SleepEx does not count the time the machine spends
  15. // sleeping/hibernating. Environment.TickCount (GetTickCount) *does* count that time,
  16. // so we will get out of sync with SleepEx if we use that method.
  17. //
  18. // So, on Win8, we use QueryUnbiasedInterruptTime instead; this does not count time spent
  19. // in sleep/hibernate mode.
  20. if (Environment.IsWindows8OrAbove)
  21. {
  22. // Based on its documentation the QueryUnbiasedInterruptTime() function validates
  23. // the argument is non-null. In this case we are always supplying an argument,
  24. // so will skip return value validation.
  25. bool success = Interop.Kernel32.QueryUnbiasedInterruptTime(out ulong time100ns);
  26. Debug.Assert(success);
  27. return (long)(time100ns / 10_000); // convert from 100ns to milliseconds
  28. }
  29. else
  30. {
  31. return Environment.TickCount64;
  32. }
  33. }
  34. }
  35. }
  36. }