Created
January 21, 2023 03:28
-
-
Save seanofw/d868c9eb782b705eaaf534412adac60d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
public class HighPrecisionSleep : IDisposable | |
{ | |
private IntPtr _waitableTimerHandle; | |
public HighPrecisionSleep() | |
{ | |
_waitableTimerHandle = Win32.CreateWaitableTimer(IntPtr.Zero, true, null); | |
Win32.timeBeginPeriod(1); | |
} | |
~HighPrecisionSleep() | |
{ | |
Dispose(false); | |
} | |
public void Dispose() | |
{ | |
Dispose(true); | |
GC.SuppressFinalize(this); | |
} | |
protected void Dispose(bool isDisposing) | |
{ | |
if (_waitableTimerHandle != IntPtr.Zero) | |
{ | |
Win32.CloseHandle(_waitableTimerHandle); | |
_waitableTimerHandle = IntPtr.Zero; | |
Win32.timeEndPeriod(1); | |
} | |
} | |
public void Sleep(long ticks) | |
{ | |
long duration = -ticks; | |
Win32.SetWaitableTimer(_waitableTimerHandle, ref duration, 0, null, IntPtr.Zero, false); | |
Win32.WaitForSingleObject(_waitableTimerHandle, -1); | |
} | |
internal static class Win32 | |
{ | |
public delegate void TimerCompleteDelegate(); | |
[DllImport("kernel32")] | |
public static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string? lpTimerName); | |
[DllImport("kernel32")] | |
public static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long ft, int lPeriod, | |
TimerCompleteDelegate? pfnCompletionRoutine, IntPtr pArgToCompletionRoutine, bool fResume); | |
[DllImport("kernel32")] | |
public static extern int WaitForSingleObject(IntPtr Handle, int Wait); | |
[DllImport("kernel32")] | |
public static extern bool CloseHandle(IntPtr hHandle); | |
[DllImport("winmm.dll")] | |
public static extern uint timeBeginPeriod(uint uMilliseconds); | |
[DllImport("winmm.dll")] | |
public static extern uint timeEndPeriod(uint uMilliseconds); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I hereby release this high-precision sleep code under the open-source MIT license. Reuse it for whatever you want. You are not obligated to credit me for it.