2

我正试图让我的电脑唤醒,以防它进入睡眠模式。我在某个网站上找到了这个代码片段,但我最后添加的 Messagebox 总是立即返回。

我还在电源选项中启用了我的系统以使用唤醒计时器。

[DllImport("kernel32.dll")]
    public static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes,
    bool bManualReset, string lpTimerName);

    [DllImport("kernel32.dll")]
    public static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long
    pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr
    lpArgToCompletionRoutine, bool fResume);

    [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
    public static extern Int32 WaitForSingleObject(IntPtr handle, uint
    milliseconds);

    static IntPtr handle;

    private void SetWaitForWakeUpTime()
    {
        long duetime = 1200000000;
        handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer");
        SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true);
        uint INFINITE = 0xFFFFFFFF;
        int ret = WaitForSingleObject(handle, INFINITE);
        MessageBox.Show("wake up !");
    }

我这样称呼它:

private void buttonTest_Click(object sender, EventArgs e)
    {
        SetWaitForWakeUpTime();
    }

从理论上讲,这应该只在 2 分钟后发出信号,对吧?为什么它会立即发出信号,我该如何纠正?

4

1 回答 1

2

SetWaitableTimer() 可以在绝对时间和增量时间上触发。来自 MSDN 文章:

pDueTime [in]
将计时器的状态设置为已发出信号的时间,以 100 纳秒为间隔。使用 FILETIME 结构描述的格式。正值表示绝对时间。请务必使用基于 UTC 的绝对时间,因为系统内部使用基于 UTC 的时间。负值表示相对时间。实际的计时器精度取决于硬件的能力。有关基于 UTC 的时间的更多信息,请参阅系统时间。

现在您使用了一个正值,因此您指定了 1600 年的日期,它总是立即完成。看起来您的实际意图是使用 2 分钟的间隔,因此您必须使用负值 -1200000000。

可能的真正意图是让它在时钟的特定时间唤醒,给定使用场景,使用 DateTime.ToUniversalTime().ToFileTime()

于 2016-03-24T17:31:07.507 回答