-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAccurateTimer.cs
More file actions
57 lines (51 loc) · 1.99 KB
/
Copy pathAccurateTimer.cs
File metadata and controls
57 lines (51 loc) · 1.99 KB
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
50
51
52
53
54
55
56
57
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Threading;
namespace CAN
{
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;
Dispatcher mDispatcher;
private int mTimerId;
private TimerEventDel mHandler; // NOTE: declare at class scope so garbage collector doesn't release it!!!
public AccurateTimer(Action action,Dispatcher dispatcher, int delay)
{
mAction = action;
mDispatcher = dispatcher;
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)
{
mDispatcher.InvokeAsync(mAction, System.Windows.Threading.DispatcherPriority.Send);
}
}
}
}