如何更快地显示所有进程的内存使用情况

本文关键字:内存 用情 情况 进程 何更快 显示 | 更新日期: 2023-09-27 18:02:32

问题是我需要在所有进程中循环每个进程。例如,在任务管理器中,它看起来像是在非常快地更新所有进程的内存使用情况,可能每秒或更少。

我有一个后台工作人员的工作事件:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            while (true)
            {
                completed = true;
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                  GetProcessesMemoryUsage();
                }
            }
        }

方法GetProcessesMemoryUsage:

private void GetProcessesMemoryUsage()
{
 foreach (Process p in Process.GetProcesses())
            {
              if (File.Exists(p.MainModule.FileName))
                    {
                     Process[] processes = Process.GetProcessesByName(p.ProcessName);
                        PerformanceCounter performanceCounter = new PerformanceCounter();
                        performanceCounter.CategoryName = "Process";
                        performanceCounter.CounterName = "Working Set";
                        performanceCounter.InstanceName = processes[0].ProcessName;
                        memoryUsage = ((uint)performanceCounter.NextValue() / 1024).ToString("N0");
                    }
           }

问题是需要一直执行foreach循环来更新每个进程的内存使用情况。

那么它是如何在任务管理器中工作的呢?他们是如何如此快速地更新所有流程的?

如何更快地显示所有进程的内存使用情况

在我的盒子上,PerformanceCounter的初始构造(包括对NextValue的第一次调用)花费了最多的时间,一遍又一遍。你可以使用Stopwatch类来自己研究这个问题。

然而,如果我保留创建的PerformanceCounter实例,NextValue的性能会变得更好,大约是第一次调用所需时间的五分之一。

naïve第一种方法,看看这在您的场景中是否足够,您可以这样做:

    private List<PerformanceCounter> pclist = new List<PerformanceCounter>();
    private void GetProcessesMemoryUsage()
    {
        // if our list is empty, populate
        if (pclist.Count == 0)
        {
            // this takes around 300 ms on my box after running this a couple of times
            foreach (Process p in Process.GetProcesses())
            {
                if (File.Exists(p.MainModule.FileName))
                {
                    Process[] processes = Process.GetProcessesByName(p.ProcessName);
                    PerformanceCounter performanceCounter = new PerformanceCounter();
                    performanceCounter.CategoryName = "Process";
                    performanceCounter.CounterName = "Working Set";
                    performanceCounter.InstanceName = processes[0].ProcessName;
                    pclist.Add(performanceCounter);
                }
            }
        }
        // this takes only around 80 msec on my box
        foreach(var pc in pclist)
        {
             memoryUsage = ((uint)pc.NextValue() / 1024).ToString("N0");
        }
    }

这意味着您现在需要一些额外的代码来监视终止的进程,以便您可以从列表中删除这些进程。