Асинхронная обработка событий 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 ()
Надеюсь это поможет