Недавно я пытался создать приложение-календарь, которое будет отображать текущий год-месяц-дату для пользователя. Проблема в том, что если пользователь будет продолжать работу моего приложения даже на следующий день, как мне получить уведомление? Как мне изменить отображаемую дату? Я не хочу опрашивать текущую дату, чтобы обновить ее. Возможно ли это в C#.
Примечание. Я пробовал событие SystemEvent.TimeChanged, но оно работает, только если пользователь вручную изменяет время / дату с панели управления.





Можете ли вы просто рассчитать количество секунд до полуночи, а затем так долго спать?
Простое решение, но не забывайте о переходе на летнее время! В противном случае вы проснетесь сразу после того, как вы думали, что это была полночь, но дата на самом деле не изменится.
Я согласен с Марком, что для сна предпочтительнее таймер. Я предусмотрел отдельный поток для обработки этого, но, вероятно, это излишне. Хотя идея та же.
Хорошее замечание от мистера Зебры. Конечно, это идет в обоих направлениях - вы можете подождать слишком долго и оставить старую дату отображаться на дополнительный час.
Кроме того, пользователь может изменить время посередине (хотя вы можете обрабатывать это событие отдельно)
Попробуйте изучить мониторинг событий WMI, вы должны иметь возможность создать запрос события Wql, который отслеживает изменение дня недели (например, ManagementEventWatcher и т. д.), А затем настроить обработчик событий, который запускается при наступлении события.
using System;
using System.Management;
class Program
{
public static void Main()
{
WqlEventQuery q = new WqlEventQuery();
q.EventClassName = "__InstanceModificationEvent ";
q.Condition = @"TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour = 22 AND TargetInstance.Minute = 7 AND TargetInstance.Second = 59";
Console.WriteLine(q.QueryString);
using (ManagementEventWatcher w = new ManagementEventWatcher(q))
{
w.EventArrived += new EventArrivedEventHandler(TimeEventArrived);
w.Start();
Console.ReadLine(); // Block this thread for test purposes only....
w.Stop();
}
}
static void TimeEventArrived(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("This is your wake-up call");
Console.WriteLine("{0}", new
DateTime((long)(ulong)e.NewEvent.Properties["TIME_CREATED"].Value));
}
}
Год, похоже, не соответствует -1600 в методе TimeEventArhibited (я получил 28 декабря 409 года в качестве даты, а не 28 декабря 2009 года). Вы знаете, почему это могло быть? Мне просто нужно прибавить 1600 к году?
Я бы заменил new DateTime (...) на DateTime.FromFileTimeUtc (...): этот метод использует 1 января 1601 года в качестве «года 0», что является правильным годом для свойства TIME_CREATED.
Ответ @ OddThinking будет работать (вы можете установить таймер для интервала вместо сна). Другой способ - установить таймер с интервалом в 1 минуту и просто проверить, не изменилась ли системная дата. Поскольку вы выполняете легкий код только раз в минуту, я сомневаюсь, что накладные расходы будут заметны.
Как насчет потока, который проверяет изменение даты. Поток может иметь некоторые события, на которые могут подписаться элементы управления, которым нужна эта информация.
public void Main()
{
var T = new System.Timers.Timer();
T.Elapsed += CallBackFunction;
var D = (DateTime.Today.AddDays(1).Date - DateTime.Now);
T.Interval = D.TotalMilliseconds;
T.Start();
}
private void CallBackFunction(object sender, System.Timers.ElapsedEventArgs e)
{
(sender as System.Timers.Timer).Interval = (DateTime.Today.AddDays(1).Date - DateTime.Now).TotalMilliseconds;
}
Что ж, какой-то таймер может быть предпочтительнее Sleep () [который уничтожит ваш пользовательский интерфейс]