2016-09-16 11 views
0

ほとんどのマシンでうまく動作するWMIコードをいくつか作成しました。しかし、いくつかのマシン(ほぼすべてのSSDベースのMac)では、このコードは大きなパフォーマンスの問題を引き起こします。これは、WMIPrvSeプロセスがI/O Otherを打ち続ける原因となります。同じ視聴をしている別のアプリケーションを実行すると、ソフトウェアが使用できなくなるまでクロールが遅くなります。WMIイベントウォッチャーのパフォーマンスの問題

  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)); 
     }