Запланированная задача.NET - WqlEventQuery выполняется каждые 30 минут

Я работаю с POC, чтобы использовать библиотеку, упомянутую в разделе Как запланировать задачу в.NET Framework (C#).

Однако я получил код для работы в определенное время. Как я могу заставить его выполняться каждые 30 минут?

Ниже дан мой основной метод:

static void Main(string[] args)
        {
            WqlEventQuery query = new WqlEventQuery("__InstanceModificationEvent", 
                new System.TimeSpan(0, 0, 1), 
                "TargetInstance isa 'Win32_LocalTime' AND TargetInstance.Hour=11 AND TargetInstance.Minute=08 AND TargetInstance.Second=59");

            ManagementEventWatcher watcher = new ManagementEventWatcher(query);
            watcher.EventArrived += Watcher_EventArrived;

            watcher.Start();
            System.Console.ReadLine();
        }

1 ответ

О, мальчик, вы вошли в страну WQL и WMI.

Win32_LocalTime описывает момент времени, поэтому вы можете настроить событие на определенное время. Если вы пытаетесь использовать его для описания интервала вместо момента времени, то вы можете проверить, равна ли текущая минута 0 или 30. Таким образом, ваше событие будет подниматься каждые час и полтора часа. Например, событие будет происходить в 18:00, 18:30, 19:00, 19:30 и т. Д. Вы можете проверить минуты, проверив TargetInstance.Minute быть 0 или 60 так:

WqlEventQuery query = new WqlEventQuery("__InstanceModificationEvent",
                      new System.TimeSpan(0, 0, 1),
                      "TargetInstance isa 'Win32_LocalTime' AND (TargetInstance.Minute=0 OR TargetInstance.Minute=30)");

Этот метод также будет работать для других минутных интервалов, таких как 15 и 45.

Однако использование этого метода имеет недостаток, заключающийся в необходимости указывать конкретные минуты вашего 30-минутного интервала. Также в зависимости от стоимости Win32_LocalTime когда вы выполняете этот код, ваше событие может сработать раньше, чем пройдет 30 минут. Например, если вы выполняете этот код в 6:45 вечера, и вы установили событие на 0 и 30 минут, то первое событие будет срабатывать через 15 минут, а не через 30 минут.

Чтобы обойти это, вы можете вместо этого использовать класс __IntervalTimerInstruction. Он специально генерирует события в интервалах. Вы используете его, создавая его экземпляр и устанавливая ManagementEventWatcher для прослушивания события __TimerEvent, которое генерируется при достижении указанного интервала.

static void Main(string[] args)
{
    ManagementClass timerClass = new ManagementClass("__IntervalTimerInstruction");
    ManagementObject timer = timerClass.CreateInstance();
    timer["TimerId"] = "Timer1";
    timer["IntervalBetweenEvents"] = 180000000; // 30 minutes in milliseconds
    timer.Put();

    WqlEventQuery query = new WqlEventQuery("__TimerEvent",
         "TimerId=\"Timer1\"");

    ManagementEventWatcher watcher = new ManagementEventWatcher(query);
    watcher.EventArrived += Watcher_EventArrived;

    watcher.Start();
    Console.ReadLine();
    watcher.Stop();
}

public static void Watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    Console.WriteLine("Event Arrived");
}

Однако следует помнить, что создание таймера с использованием __IntervalTimerInstruction Документация Microsoft считается устаревшей техникой. Кроме того, мне пришлось запустить мой экземпляр Visual Studio в режиме администратора, чтобы запустить его.

Чтобы увидеть еще один пример настройки таймера с __IntervalTimerInstructionсмотрите здесь.

Другие вопросы по тегам