WMI事件监视程序性能问题

本文关键字:性能 问题 程序性 程序 事件 监视 WMI | 更新日期: 2023-09-27 18:07:17

我编写了一些在大多数机器上运行良好的WMI代码。然而,在某些机器上(几乎所有基于SSD的mac),这段代码会导致巨大的性能问题。它导致WMIPrvSe进程不断地访问I/O Other。如果你运行另一个应用程序做同样的观察,那么它会慢到无法使用的程度。

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

有人知道这里可能发生了什么吗?如果我删除这段代码,那么它的工作完美。在其他机器上,它运行得很好。这很奇怪。任何想法都非常感谢!

WMI事件监视程序性能问题

所以我还没有弄清楚是什么导致了这个问题,但我现在已经使用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 ) );
        }