C # event to detect daylight saving time or even manual time change

I run my application as a service on a server and then connect multiple clients to that service. I am showing the exact server time in every client window application window and because of this I need a mechanism to detect any time changes on the server so that I can send it to the client for display.

Looking around on MSDN I found SystemEvents.TimeChanged, I thought I was in luck because when testing with the code below with Visual Studio everything works fine:

SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged);

static void SystemEvents_TimeChanged(object sender, EventArgs e)
        //Occurs when user manually changes the time or due to
        //daylight saving time.  Server will issue its latest time
        //to all the clients so time can be adjusted.


Unfortunately when I run this as a service this event will never be fired because looking at the fine print on MSDN the TimeChanged event is only triggered in the application with the message (for example it must have a form started) It works in Visual Studio because it has a shape when I run it as no maintenance mode.

I can fix this by checking the "Allow the service to interact with the desktop" checkbox, but this view defeats the purpose of my application running as a service.

I could create a timer event in the application to check for a time change, say every 10 seconds or so, but this is a big overhead to check for a random time change that happens on the server machine twice or maybe 3 times a year ...

So, does anyone know a C # event that fires on time change that runs in an application that doesn't have a message pump? I wonder if Microsoft doesn't include an event that works this way.



source to share

3 answers

Thanks to everyone for your contributions, they have definitely pointed me in the right direction. I managed to solve my problem and I think they will be posted here for anyone who finds them useful.

So, in my main program where I start the service, it must be a subclass of ServiceBase.

In my main function, I spawned a separate thread like this:

new Thread(RunMessagePump).Start();

private void RunMessagePump()
  Application.Run(new HiddenForm())


This hidden form is exactly what its name says, it is a simple form that remains hidden by the this.ResumeLayout (false) code under its Intiailaizecomponent () code.

Within this form of FormLoad events, you can declare any system event. In my case, I have

private void HiddenForm_Load(object sender,EventArgs e)
  SystemEvents.timeChanged += new EventHandler(SystemEvents_TimeChanged);


Voila, this works nicely and I think I will use this form load event to capture any SystemEvents I want to use along the way.




Ok, I would strongly suggest not relying on local time to get started. Use the server's UTC time, and then if you need to convert it to local time, you can do it wherever you want if you know your timezone.

Detecting a manual time change without a useful event is a little harsher, but you could just start a timer that runs every (say) 30 seconds and checks if UTC is "UTC time, at least a timer + 30 seconds" "with some degree of tolerance?

You don't need to run this very often, so it's not like it would be a huge waste of resources. You can always hide this behind an API that can be replaced with a more efficient one if you ever find a better answer :)



Perhaps less than ideal, you might have an agent running in the foreground that listens for the TimeChanged event and forwards it to your service.



All Articles