2016-09-16 68 views
0

我寫過一些WMI代碼,在大多數機器上運行得非常好。但是在某些機器上(幾乎所有基於SSD的mac)都會導致巨大的性能問題。它導致WMIPrvSe進程繼續擊中I/O Other。如果您運行另一個應用程序來進行同樣的觀察,那麼它會慢慢爬到軟件無法使用的地步。WMI Event Watcher性能問題

  System.Management.WqlEventQuery  queryIn; 
      System.Management.WqlEventQuery  queryOut; 
      System.Management.ManagementScope scope = new System.Management.ManagementScope("root\\CIMV2"); 
      scope.Options.EnablePrivileges  = true; 

      try 
      { 
       queryIn = new System.Management.WqlEventQuery(); 
       queryIn.EventClassName   = "__InstanceCreationEvent"; 
       queryIn.WithinInterval   = new TimeSpan(0, 0, 1); 
       //queryIn.GroupWithinInterval  = new TimeSpan(0, 0, 0); 
       queryIn.Condition    = @"TargetInstance ISA 'Win32_DiskDrive' AND TargetInstance.InterfaceType = 'USB'"; 
       mUSBWatcherIn = new System.Management.ManagementEventWatcher(scope, queryIn); 

       //adds event handler that’s is fired when the insertion event occurs 
       mUSBWatcherIn.EventArrived += new System.Management.EventArrivedEventHandler(USBInserted); 

       queryOut = new System.Management.WqlEventQuery(); 
       queryOut.EventClassName   = "__InstanceDeletionEvent"; 
       queryOut.WithinInterval   = new TimeSpan(0, 0, 1); 
       //queryOut.GroupWithinInterval = new TimeSpan(0, 0, 0); 
       queryOut.Condition    = @"TargetInstance ISA 'Win32_DiskDrive' AND TargetInstance.InterfaceType = 'USB'"; 
       mUSBWatcherOut = new System.Management.ManagementEventWatcher(scope, queryOut); 

       //adds event handler that’s is fired when the insertion event occurs 
       mUSBWatcherOut.EventArrived += new System.Management.EventArrivedEventHandler(USBRemoved); 

       mUSBWatcherIn.Start();//run the watcher 
       mUSBWatcherOut.Start(); 
      } 
      catch (Exception e) 
      { 
       System.Windows.Forms.MessageBox.Show(e.Message); 
       StopUSBWatcher(); 
      } 

有沒有人有任何想法可以在這裏發生什麼?如果我刪除此代碼,那麼它完美的作品。在其他機器上,它完美地工作。它非常奇怪。任何想法非常感謝!

回答

0

所以我還沒有找出導致問題的原因,但現在我已經使用WM_DEVICECHANGE實現了相同的功能。

這裏是我的互操作設置:

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] 
    private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags); 

    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] 
    private static extern bool UnregisterDeviceNotification(IntPtr handle); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr newLong); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int newLong); 


    delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 

    public const int    GWLP_WNDPROC = -4; 

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 
    private struct DevBroadcastDeviceinterface 
    { 
     internal int Size; 
     internal int DeviceType; 
     internal int Reserved; 
     internal Guid ClassGuid; 
     internal short Name; 
    } 

    const int DBT_DEVTYPVOLUME = 0x00000002; 
    const int DBT_DEVTYPDEVICEINTERFACE = 5; 

    static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); 

和實際設置代碼如下:

 DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface 
      { 
       DeviceType = DBT_DEVTYPDEVICEINTERFACE,//DBT_DEVTYPVOLUME, 
       Reserved = 0, 
       ClassGuid = GuidDevinterfaceUSBDevice, 
       Name = 0 
      }; 

     dbi.Size = System.Runtime.InteropServices.Marshal.SizeOf(dbi); 
     IntPtr buffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(dbi.Size); 
     System.Runtime.InteropServices.Marshal.StructureToPtr(dbi, buffer, true); 

     IntPtr i = RegisterDeviceNotification(Handle, buffer, 0); 

     System.Runtime.InteropServices.Marshal.FreeHGlobal(buffer); 

     if (IntPtr.Size == 4) 
     { 
      oldWndProc = new IntPtr(SetWindowLong(Handle, GWLP_WNDPROC, System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(newWndProc).ToInt32())); 
     } 
     else 
     { 
      oldWndProc = SetWindowLongPtr(Handle, GWLP_WNDPROC, System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(newWndProc)); 
     }