WMI 性能不佳
我用 C# 编写了一段代码,使用 WMI (System.Management) 将逻辑驱动器映射到其物理磁盘。 代码运行完美,但速度慢得要命。 在我的机器(Windows 7 x64,双核,3 GB RAM)中,它运行至少 1 秒。 1秒对我来说太慢了,即使0.1秒也绰绰有余了。 我非常恼火的是这个功能可以在不到 0.1 秒的时间内完成。
有没有 Win32API 函数可以提供帮助?
还有其他建议吗?
这是我到目前为止的代码:
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);
}
}
}
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);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好吧,这里有一些代码至少在我的系统上运行得更快(从客观的角度来看)并给出相同的结果。由于驱动器列表几乎不可能每秒改变,我不确定为什么你真的这么关心,但无论如何,看看这是否会让你更快乐。您可以通过删除开始时获取 Win32_DiskDrive 的代码来稍微加快速度,但祝您好运,让它在 0.1 秒内运行:)
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 :)
这是我的最终代码,比第一个版本快 23 倍,基于使用 Win32_LogicalDiskToPartition 的暴君想法。
This is my final code, x23 faster than the first version, based on tyranid idea to use Win32_LogicalDiskToPartition.
我发现最好的途径是从 4 个类中的每一个获取完整数据,然后使用 LINQ 进行连接,以尽量减少对 WMI 服务的影响(因为它在负载下速度很慢)。
一开始你可能会认为这听起来很可怕,但是测试一下看看我在说什么。
I have found that the best route is to get the full data from each of the 4 classes and then do your joining with LINQ to minimize the impact on the WMI service (as it is slow under load).
As first you might think that sounds horrible, but test it out to see what I am talking about.
请参阅有关 GetLogicalDrives、GetLogicalDriveStrings、GetDriveType 的这篇文章(包含代码示例)和 GetVolumeInformation
要查找物理驱动器,您可以使用
FindFirstVolume
和FindNextVolume
(我得到“\.\Device{uiid}”。与GetVolumePathNamesForVolumeNameW
结合使用> 获取关联的驱动器盘符,然后您可以通过上述API获取您想要的信息。如果您需要分区/磁盘编号,请参阅 DeviceIoControl为了获取该信息,
我认为您需要代码中的
results
中的内容。see this article (with code sample) about GetLogicalDrives, GetLogicalDriveStrings, GetDriveType, and GetVolumeInformation
To find physical drives, you can use
FindFirstVolume
andFindNextVolume
(I get "\.\Device{uiid}". Combined withGetVolumePathNamesForVolumeNameW
to get the associated drive letter. Then you can get the info you want with above mentioned APIs.If you need partition/disk numbers see DeviceIoControl to get that info
I thought you needed what is in
results
in your code.