C#中的Process.Modules非常缓慢。

5

我的代码提取了每个正在运行的进程中已加载模块的所有名称,我的方法如答案所述。

这是我的代码:

Process[] procs = Process.GetProcesses();            
foreach (Process p in procs)
{                  
    foreach (ProcessModule item in p.Modules)
    {
        Console.WriteLine(item.FileName);
    }
}

由于某些原因,这种方法的性能非常低 :(

是否有其他方法或不同的方法可以获取所有这些模块的名称?

任何运行速度比这个更快的其他解决方案都将是很好的选择。

TIA


3
“非常低的表现”有多低? - Philip Pittle
@PhilipPittle 仅使用39个进程处理2097个模块,耗时731毫秒。 - Eli
tasklist /M 更快吗? - rene
我不确定,但我认为在 Redmond 的那些人知道如何高效地迭代模块列表...如果你的实现达到了命令行的性能,那么你必须假设本机 Win32 API 不会提供更多速度。 - rene
@David_001 我得到了2097模块在39个进程中的731毫秒。 - Eli
显示剩余3条评论
1个回答

3
您可以尝试添加一些并行处理来加速操作:
 Parallel.ForEach(Process.GetProcesses(),
            process =>
            {
                foreach (ProcessModule m in process.Modules)
                {
                    Console.WriteLine(m.FileName);
                }
            });

2
@Eli 你确定这不会有影响吗?我尝试了一下,这是我的结果 - Measurity
2
@Eli - 你在使用具有多个CPU核心的计算机吗? - Philip Pittle
@目前测量结果似乎并不稳定。我会尝试像你一样取50个平均值... - Eli
1
@PhilipPittle 不是一个好的评论 - 看起来并不是并行化不能提高性能的原因。无论如何,我正在使用虚拟机,我将使用更多的核心进行测试,但是它仍然是一个非常慢的机制。 - Eli
1
@Eli - 是的,从所有进程中收集模块是一个相当缓慢的过程。除了向操作系统请求信息外,没有其他获取此信息的方法。而且操作系统不会“缓存”此信息,因此必须从每个正在运行的进程中获取它。从操作系统的角度来看,缓存这些信息并没有太多好处,因此不值得承担内存开销。这就是为什么,正如rene所指出的那样,即使是tasklist /M也相对较慢的原因。 - Philip Pittle
@PhilipPittle 好的,那我就接受你的答案了 - 我试了50次,平均来看并行处理的效果更好(尽管我目前只用单核运行) 非常感谢 :) - Eli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接