Событие C # для обнаружения перехода на летнее или даже ручное изменение времени - PullRequest
3 голосов
/ 15 марта 2012

Я запускаю приложение в качестве службы на сервере, а затем у меня есть несколько клиентов, подключающихся к этой службе.Я отображаю точное время сервера в каждом клиентском приложении формы окна, и поэтому мне нужен механизм для обнаружения любого изменения времени на сервере, чтобы я мог отправить его клиенту для отображения.

ПросмотрMSDN, который я нашел SystemEvents.TimeChanged, я подумал, что мне повезло, потому что при тестировании с кодом ниже в Visual Studio все работает отлично:

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.
    }

К сожалению, когда я запускаю это как службу, это событие будетникогда не запускаться, потому что, глядя на мелкий шрифт на MSDN, событие TimeChanged запускается только в приложении с активным насосом сообщений (он же должен иметь запущенную форму).Он работает в Visual Studio, потому что у него есть форма, когда я запускаю его как не сервисный режим.

Я могу исправить это, выбрав опцию «Разрешить сервису взаимодействовать с рабочим столом», но это не соответствует целия пытаюсь запустить приложение в качестве службы.

Я мог бы создать событие отметки времени в приложении для проверки изменения времени, скажем, каждые 10 секунд или около того, но это большие затраты, просто чтобы проверитьслучайное изменение времени, которое происходит на сервере дважды или, может быть, 3 раза в год.

Таким образом, кто-нибудь знает событие C #, которое вызывает изменение времени, которое работает в приложении, в котором не работает насос сообщений?Я удивлен, если Microsoft не включает событие, которое работает таким образом

Спасибо.

Ответы [ 3 ]

4 голосов
/ 21 марта 2012

Спасибо всем за ваш вклад, они, безусловно, указали мне в правильном направлении. Я смог решить свою проблему и решил разместить их здесь для всех, кто найдет их полезными.

Так что в моей основной программе, где я запускаю службу, это должен быть подкласс ServiceBase.

В моей основной функции я создал отдельную ветку следующим образом:

new Thread(RunMessagePump).Start();

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

Эта скрытая форма в точности соответствует названию. Это простая форма, которая остается скрытой кодом this.ResumeLayout (false) под его кодом Intiailaizecomponent ().

В событии FormLoad этой формы вы можете объявить любое системное событие. В моем случае у меня есть

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

Вуаля, это прекрасно работает, и я думаю, что я буду использовать это событие загрузки формы для захвата любых событий SystemEvents, которые я хочу использовать в будущем.

Приветствие.

3 голосов
/ 15 марта 2012

Ну, я бы настоятельно рекомендовал не полагаться на местное время для начала.Используйте UTC-время сервера, а затем, если вам нужно преобразовать его в местное время, вы можете сделать это где угодно, если вы знаете его часовой пояс.

Обнаружение изменения времени вручную без полезногоСобытие немного сложнее, но не могли бы вы просто запустить таймер, который запускается каждые (скажем) каждые 30 секунд и проверяет, не является ли время UTC «UTC время, по крайней мере, отметка таймера + 30 секунд» с некоторой степенью допуска?1006 * Вам не нужно часто запускать его ужасно, так что это не будет огромной тратой ресурсов.Вы всегда можете скрыть это за API, который можно заменить на более эффективный, если вы когда-нибудь do найдете лучший ответ:)

0 голосов
/ 15 марта 2012

Возможно, не идеально, у вас может быть агент, работающий на переднем плане, который прослушивает событие TimeChanged и перенаправляет его в вашу службу.

...