Асинхронная обработка событий WMI в.NET

Я пытаюсь запустить некоторые процессы удаленно, используя WMI, и ожидаю завершения процесса. В настоящее время наблюдатель событий является полусинхронным с использованием WaitForNextEvent который также имеет тайм-аут на случай, если что-то случится с программой. Все это работает хорошо. Я попытался изменить это на асинхронную обработку событий, но я получаю ошибку Access Denied при запуске средства отслеживания событий. Теперь это не будет иметь большого значения, потому что я могу придерживаться полусинхронного метода, но есть одно исключение.

Если по какой-либо причине во время выполнения программы машина перезапускается, зависает или теряет сетевое соединение, WaitForNextEvent не генерирует исключение тайм-аута, но блокирует поток на неопределенный срок (я оставил его там на 10 минут без ответа, тайм-аут был 30 секунд). У меня вопрос: знает ли кто-нибудь, можно ли настроить средство наблюдения за событиями определенным образом для тайм-аута независимо от соединения или для настройки на стороне клиента, чтобы иметь доступ к асинхронным разрешениям. Обычно первый вариант предпочтительнее, но второй вариант тоже возможен.

ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
    new WqlEventQuery(
        "select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));

w.Options.Timeout = new TimeSpan(0, 0, 0, 30);

var ev = w.WaitForNextEvent();

Я хотел бы знать, есть ли в ManagementeventWatcher некоторые параметры для возврата или тайм-аута независимо от соединения, или можно использовать асинхронный метод для захвата событий.

Решение

ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
    new WqlEventQuery(
        "select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));

w.Options.Timeout = new TimeSpan(0, 0, 0, 0, 1);
DateTime start = DateTime.Now;
while (Status == StatusNotStarted) //default status(just strings)
{
    try
    {
        var ev = w.WaitForNextEvent();
        ReturnCode = (uint)ev.Properties["ExitStatus"].Value;
        Status = (ReturnCode == 0) ? StatusOk : StatusFailed;
    }
    catch (ManagementException ex)
    {
        if (!ex.Message.Contains("Timed out"))
        {
            throw ex;
        }
        try
        {
            Ping p = new Ping();
            PingReply reply = p.Send(MachineIP);
            if (reply.Status != IPStatus.Success)
            {
                Status = StatusFailed;
            }
            else
            {
                DateTime end = DateTime.Now;
                TimeSpan duration = end - start;
                if (duration.TotalMilliseconds > Timeout)
                {
                    Status = StatusFailed;
                }
            }
        }
    }
}

1 ответ

Этот ответ описывает способ реализации неблокирующей WaitForNextEvent ()

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c2b6a2f4-eb84-4bbb-acdb-bbef4b0611e6/nonblocking-managementeventwatcherwaitfornextevent?forum=csharpgeneral

Надеюсь это поможет

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