我正在尝试在 C# 中创建一个例如 30 分钟的周期性计时器,它能够将计算机从睡眠中唤醒并开始工作。
在网络上进行一些研究后,似乎应该使用 Waitable 计时器功能。我已经制作了一些测试代码,但它并没有像我希望的那样工作。当我调试和单步执行代码时,可以创建计时器并多次调用回调。但是当我在没有任何断点的情况下运行代码时,回调只会被调用几次。
我制作了一个表单应用程序,在按下按钮时运行“testWaitableTimer”。“myTimerEvent”应该打印每个定时器事件的时间。我不想在测试时等待 30 分钟超时,因此将时间段设置为 2 秒间隔和 5 秒的到期时间。
public void myTimerEvent(IntPtr complretionArg, UInt32 timerLow, UInt32 timerHigh)
{
SetText( DateTime.Now.ToString() + "hepp ");
}
public delegate void TimerCompleteDelegate(IntPtr complretionArg,
UInt32 timerLow, UInt32 timerHigh);
[DllImport("kernel32.dll")]
public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, TimerCompleteDelegate pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume);
SafeWaitHandle handle;
private void testWaitableTimer()
{
DateTime utc = DateTime.Now.AddSeconds(5);
long duetime = utc.ToFileTime();
using (handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer"))
{
// create a periodic timer that will fire of the first event after 5sec and then every 2 sec
if (SetWaitableTimer(handle, ref duetime, 2000, myTimerEvent, IntPtr.Zero, true))
{
using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset))
{
wh.SafeWaitHandle = handle;
wh.WaitOne(); // wait for first event
System.Threading.Thread.Sleep(2000);
wh.WaitOne(); // wait for second event
System.Threading.Thread.Sleep(500);
wh.WaitOne(); // wait for third event.
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
我对 C# 很陌生,有一些问题:
运行代码时,多次调用 wh.WaitOne(),但它似乎只等待第一个计时器事件。如果所有“睡眠”功能都被删除,代码将等待第一个,然后跳过其余的。
我在 testfunction 之外创建了 safeWaitHandle。但似乎只有在运行 testfunction 时才会调用计时器回调。并在退出测试功能时停止执行。这是为什么?