SystemEvents.TimeChanged触发两次

时间:2013-02-24 14:22:20

标签: c#

我在Windows应用程序中使用事件SystemEvents.TimeChanged,它会触发两次。 我使用的代码:

using System;
using Microsoft.Win32;

namespace DateTimeTests
{
    class Program
    {
        static void Main(string[] args)
        {
            SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged);
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        static void SystemEvents_TimeChanged(object sender, EventArgs e)
        {
            Console.WriteLine("Time changed: {0}", DateTime.Now);
        }
    }
}

我尝试在Windows中更改时间,事件发生两次。为什么呢?

4 个答案:

答案 0 :(得分:3)

答案 1 :(得分:1)

只要收到WM_TIMECHANGE message,它就会触发事件。因此,您需要查找其他程序两次更改时间的原因,或者可能过于热心地更改系统时间广播此消息。很难推测,因为你没有描述你为改变时间做了什么。

当然,这应该从不成为一个真正的问题。

答案 2 :(得分:1)

手动设置时钟时,确实会发生SystemEvents.TimeChanged令人反感的重复射击。当您从手动->自动切换日期和时间设置时也会发生这种情况(假设结果是调整了时钟):

enter image description here

是的,这似乎是Windows问题。 有一个简单的解决方法:使用反应性扩展包装SystemEvents.TimeChanged事件并忽略无关的事件。

1)从Nuget安装System.Reactive 2)使用类似于以下代码:

using Microsoft.Win32;
using System;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            IDisposable subscriptionToken = 
                Observable.FromEventPattern(e => SystemEvents.TimeChanged += e, e => SystemEvents.TimeChanged -= e)
                .Select(x => new Unit())
                .Throttle(TimeSpan.FromMilliseconds(250))
                .Subscribe(x => Console.WriteLine("The system clock just changed"));

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

            subscriptionToken.Dispose();
        }
    }
}

即使在250毫秒的时间范围内触发了两个以上的事件,这也将起作用。只有最后一个会被执行

答案 3 :(得分:0)

在第一次解雇此事件时解除关联并解决问题:

static void SystemEvents_TimeChanged(object sender, EventArgs e)
{
    SystemEvents.TimeChanged -= new EventHandler(SystemEvents_TimeChanged);

    Console.WriteLine("Time changed: {0}", DateTime.Now);
}