WMI事件监视器性能问题

时间:2016-09-16 11:00:23

标签: c# performance wmi wmi-query wmi-service

我编写了一些在大多数机器上运行良好的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();
            }

有谁知道这里会发生什么?如果我删除此代码,那么它完美地工作。在其他机器上,它完美运行。这很奇怪。任何想法都非常感激!

1 个答案:

答案 0 :(得分: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 ) );
        }