ManagementEventWatcher теряет события в C#

Я разрабатываю приложение, которое использует ManagementEventWatcher контролировать USB События. Код работает правильно, но в некоторых случаях программа теряет некоторые USB events, Как правильно составить список всех событий с USB?

Я использую следующий код, я использую два запроса для подключения монитора и отсоединения от USB. Мне нужно контролировать много портов USB.

USB-монитор

    ManagementEventWatcher watchUSBattach = new ManagementEventWatcher();
    ManagementEventWatcher watchUSBDettach = new ManagementEventWatcher();

    WqlEventQuery queryUsbAttach = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2 ");
    watchUSBattach.EventArrived += new EventArrivedEventHandler(watchUSBEventAdd);
    watchUSBattach.Query = queryUsbAttach;
    watchUSBattach.Start();

    WqlEventQuery queryUsbDettach = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 3");
    watchUSBDettach.EventArrived += new EventArrivedEventHandler(watchUSBEventDettach);
    watchUSBDettach.Query = queryUsbDettach;
    watchUSBDettach.Start();

1 ответ

Я наблюдал аналогичную вещь при мониторинге для вставки или удаления USB-устройства. Пример кода ниже. Когда WithinInterval свойство установлено на 1 мс, тогда я не пропускаю события, но вместо этого я испытываю необоснованную нагрузку на процессор в WMIProviderHost и связанной службе. Если я установлю более разумное значение, например 3 секунды, я пропущу события удаления / создания, если они происходят слишком быстро с одного устройства (например, если устройство перезагружается). Возможно с вашим запросом по умолчанию WithinInterval слишком длинный и вызывает отбрасывание событий?

WqlEventQuery q;
var scope = new ManagementScope("root\\CIMV2") 
  {Options = {EnablePrivileges = true}};

q = new WqlEventQuery
{
  EventClassName = "__InstanceCreationEvent",
  WithinInterval = TimeSpan.FromMilliseconds(1),
  Condition = @"TargetInstance ISA 'Win32_USBControllerdevice'"
};
InsertWatcher = new ManagementEventWatcher(scope, q);
InsertWatcher.EventArrived += (sender, args) =>
{
  var instance = (ManagementBaseObject) args.NewEvent["TargetInstance"];
  RaiseInserted(new PlugEventArgs {DevicePath = (string) instance["__PATH"]});
};
InsertWatcher.Start();
Другие вопросы по тегам