Search code examples
c#.netperformancewmidisk

WMI Poor Performance


I wrote a code in C# that maps logical drives to their physical disks, using WMI (System.Management). The code working perfectly, but slow like hell. In my machine (Windows 7 x64, Dual-Core with 3 GB RAM) it runs as least 1 second. 1 second is too slow for me, even 0.1 is more than enough to accomplish. I more than sore that this functionallity can be done in less than 0.1 second.

Is there any Win32API functions that can help?

Any other suggestions?

this is my code so far:

List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();

using (ManagementClass diskDriveClass = new ManagementClass(@"Win32_Diskdrive"))
{
    using (ManagementObjectCollection diskDrives = diskDriveClass.GetInstances())
    {
        foreach (ManagementObject diskDrive in diskDrives)
        {
            string deviceId = (string)diskDrive["DeviceId"];
            Dictionary<string, string> logicalDisksResults = new Dictionary<string, string>();
            Trace.WriteLine(deviceId);

            using (ManagementObjectCollection relatedPartitions = diskDrive.GetRelated("Win32_DiskPartition"))
            {
                foreach (ManagementObject relatedPartition in relatedPartitions)
                {
                    Trace.WriteLine("-\t" + relatedPartition["Name"]);

                    using (ManagementObjectCollection relatedLogicalDisks = relatedPartition.GetRelated("Win32_LogicalDisk"))
                    {
                        foreach (ManagementBaseObject relatedLogicalDisk in
                        relatedLogicalDisks)
                        {
                            Trace.WriteLine("\t-\t" + relatedLogicalDisk["Name"] + " " + relatedLogicalDisk["FileSystem"]);
                            logicalDisksResults.Add((string)relatedLogicalDisk["Name"], (string)relatedLogicalDisk["FileSystem"]);
                        }
                    }
                }
            }

            results.Add(logicalDisksResults);
        }
    }
}

Solution

  • Well here is some code which at least on my system runs (from an objective point of view) quicker and gives the same results. As the list of drives is barely likely to change on a second by second basis I am not sure why you really care so much, but anyway, see if this makes you happier. You can speed it slightly by removing the code getting Win32_DiskDrive at the start, good luck making it run in 0.1s though :)

    Dictionary<string, Dictionary<string, string>> results = new Dictionary<string,Dictionary<string,string>>();            
    
    ManagementClass diskPartMap = null;
    ManagementObjectCollection diskPartIns = null;
    ManagementClass partLogicalMap = null;
    ManagementObjectCollection partLogicalIns = null;
    
    try
    {
        using (ManagementClass diskDriveClass = new ManagementClass("Win32_Diskdrive"))
        {
            using (ManagementObjectCollection diskDrives = diskDriveClass.GetInstances())
            {
                foreach (ManagementObject diskDrive in diskDrives)
                {
                    results.Add((string)diskDrive["DeviceId"], new Dictionary<string, string>());
                }
            }
        }
    
        Dictionary<string, ManagementObject> partToDisk = new Dictionary<string, ManagementObject>();
        Dictionary<string, ManagementObject> partToLogical = new Dictionary<string, ManagementObject>();
    
        diskPartMap = new ManagementClass("Win32_DiskDriveToDiskPartition");
        diskPartIns = diskPartMap.GetInstances();
        foreach (ManagementObject diskDrive in diskPartIns)
        {
            ManagementObject o = new ManagementObject((string)diskDrive["Antecedent"]);
            partToDisk.Add((string)diskDrive["Dependent"], o);
        }
    
        partLogicalMap = new ManagementClass("Win32_LogicalDiskToPartition");
        partLogicalIns = partLogicalMap.GetInstances();
        foreach (ManagementObject diskDrive in partLogicalIns)
        {
            ManagementObject o = new ManagementObject((string)diskDrive["Dependent"]);
            string s = (string)diskDrive["Antecedent"];
    
            partToLogical.Add(s, o);
        }
    
        foreach (KeyValuePair<string, ManagementObject> pair in partToDisk)
        {
            string deviceId = (string)pair.Value["DeviceId"];
            Dictionary<string, string> dict = null;
            if (!results.ContainsKey(deviceId))
            {
                dict = new Dictionary<string, string>();
                results[deviceId] = dict;
            }
            else
            {
                dict = results[deviceId];
            }
    
            if (partToLogical.ContainsKey(pair.Key))
            {
                ManagementObject o = partToLogical[pair.Key];
                dict.Add((string)o["Name"], (string)o["FileSystem"]);
            }
        }
    }
    finally
    {
        if (diskPartIns != null)
        {
            diskPartIns.Dispose();
            diskPartIns = null;
        }
    
        if (diskPartMap != null)
        {
            diskPartMap.Dispose();
            diskPartMap = null;
        }
    
        if (partLogicalIns != null)
        {
            partLogicalIns.Dispose();
            partLogicalIns = null;
        }
    
        if (partLogicalMap != null)
        {
            partLogicalMap.Dispose();
            partLogicalMap = null;
        }
    }