-
Notifications
You must be signed in to change notification settings - Fork 13
/
AccurateTimer.cs
49 lines (44 loc) · 1.7 KB
/
AccurateTimer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// AccurateTimer.cs
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SKOrderTester
{
class AccurateTimer
{
private delegate void TimerEventDel(int id, int msg, IntPtr user, int dw1, int dw2);
private const int TIME_PERIODIC = 1;
private const int EVENT_TYPE = TIME_PERIODIC;// + 0x100; // TIME_KILL_SYNCHRONOUS causes a hang ?!
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int msec);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int msec);
[DllImport("winmm.dll")]
private static extern int timeSetEvent(int delay, int resolution, TimerEventDel handler, IntPtr user, int eventType);
[DllImport("winmm.dll")]
private static extern int timeKillEvent(int id);
Action mAction;
Form mForm;
private int mTimerId;
private TimerEventDel mHandler; // NOTE: declare at class scope so garbage collector doesn't release it!!!
public AccurateTimer(Form form, Action action, int delay)
{
mAction = action;
mForm = form;
timeBeginPeriod(1);
mHandler = new TimerEventDel(TimerCallback);
mTimerId = timeSetEvent(delay, 0, mHandler, IntPtr.Zero, EVENT_TYPE);
}
public void Stop()
{
int err = timeKillEvent(mTimerId);
timeEndPeriod(1);
System.Threading.Thread.Sleep(100);// Ensure callbacks are drained
}
private void TimerCallback(int id, int msg, IntPtr user, int dw1, int dw2)
{
if (mTimerId != 0)
mForm.BeginInvoke(mAction);
}
}
}