WMI is being too slow

本文关键字:slow too being is WMI | 更新日期: 2023-09-27 18:29:37

是否有方法限制WMI使用WQL语句检索的条目数?我这么说是因为运行查询来检索所有Win32_NTLogEvent实例需要花费很长时间!我真正需要的只是最近的事件(大约一周,或2000个条目)

下面是我用来获取日志数据的代码片段。其他查询,如Win32_Processor,既好又快。

            if (Configuration.OnlyErrorLogs)
            {
                // If Information logs should be suppressed, only get events where event type is not 3
                WMIDataTemp1 = DataRetriever.GetWMIData("Win32_NTLogEvent", "EventType<>3");
            }
            else
            {
                WMIDataTemp1 = DataRetriever.GetWMIData("Win32_NTLogEvent");
            }
            foreach (ManagementObject Object in WMIDataTemp1)
            {
                this.Log.Add(new Log(Object));
            }

获取WMI数据的功能如下:

    public static ManagementObject[] GetWMIData(string wmiClass) { return GetWMIData(wmiClass, "", "CIMV2"); }
    public static ManagementObject[] GetWMIData(string wmiClass, string whereClause) { return GetWMIData(wmiClass, whereClause, "CIMV2"); }
    public static ManagementObject[] GetWMIData(string wmiClass, string whereClause, string nameSpace)
    {
        try
        {
            // If a where clause has been set, prepare the clause to add to the query string
            if (whereClause != "")
            {
                whereClause = " WHERE " + whereClause;
            }
            // Create a search query
            string query = "SELECT * FROM " + wmiClass + whereClause;
            ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher("root''" + nameSpace, query);
            ManagementObjectCollection matches = wmiSearcher.Get();
            // Create an array to hold the matches
            ManagementObject[] matchArray = new ManagementObject[matches.Count];
            // If matches found, copy to output
            if(matches.Count > 0)
            {
                // Copy the search matches into this array
                matches.CopyTo(matchArray, 0);
            }
            // Return array
            return matchArray;
        }
        catch (Exception e)
        {
            ErrorDialogue errorReporter = new ErrorDialogue(e);
            return null;
        }
    }

每个日志的存储位置:

public class Log
{
    public string Category = "N/A";
    public string DateTime = "N/A";
    public UInt16 ID = 0;
    public string Level = "N/A";
    public string Message = "N/A";
    public string Source = "N/A";
    public Log() { }
    public Log(ManagementObject wmiLogEvent)
    {
        this.GetInfo(wmiLogEvent);
    }
    public void GetInfo(ManagementObject wmiLogEvent)
    {
        try
        {
            this.Category = DataRetriever.GetValue(wmiLogEvent, "CategoryString");
            this.DateTime = DataRetriever.GetValue(wmiLogEvent, "TimeGenerated");
            this.ID = DataRetriever.GetValueUInt16(wmiLogEvent, "EventIdentifier");
            this.Level = DataRetriever.ConvertEventType(DataRetriever.GetValueUInt16(wmiLogEvent, "CategoryString"));
            this.Message = DataRetriever.GetValue(wmiLogEvent, "Message");
            this.Source = DataRetriever.GetValue(wmiLogEvent, "SourceName");
        }
        catch (Exception e)
        {
            ErrorDialogue errorReporter = new ErrorDialogue(e);
        }
    }
}

WMI is being too slow

一个选项是使用WHERE子句来指定所需条目的范围。。。

例如,您可以在WHERE子句中使用TimeGenerated来指定基于时间的范围。。。

另一个选项是在创建ManagementObjectSearcher时相应地设置BlockSize

例如,您可以使用它来指定每次调用需要2000个条目,再加上ORDER BY TimeGenerated DESC,这应该会产生不错的结果。

速度不适合WMI。它往往是记忆密集型的。然而,这个问题已经解决了,你可以做一些事情。看看为什么我的查询需要这么长时间才能完成?来自Microsoft TechNet。

现在使用System.Diagnostics.EventLog类作为更快的替代方法。与WMI相比,对程序更有利。

http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx