2011-05-07 62 views
1

这是一个问题的两个部分。
我有一个类,获取CPU使用率异步所有流程和调查他们。昨天我有一个错误,它解决了here
问题的第一部分就是为什么解决方案帮助。我不明白这个解释。
问题的第二部分是我偶尔会遇到一个"Object reference not set to an instance of object"异常,当我在流程结束时尝试打印结果时。这是因为item.Key确实为空。我不明白为什么这是因为我把一个断点检查为(process == null),它从未被击中。我究竟做错了什么?
代码如下。任务并行库 - 我不明白我在做什么错

class ProcessCpuUsageGetter 
    { 
     private IDictionary<Process, int> _usage; 

     public IDictionary<Process, int> Usage { get { return _usage; } } 

     public ProcessCpuUsageGetter() 
     { 
      while (true) 
      { 
       Process[] processes = Process.GetProcesses(); 
       int processCount = processes.Count(); 
       Task[] tasks = new Task[processCount]; 

       _usage = new Dictionary<Process, int>(); 
       for (int i = 0; i < processCount; i++) 
       { 
        var localI = i; 
        var localProcess = processes[localI]; 
        tasks[localI] = Task.Factory.StartNew(() => DoWork(localProcess)); 
       } 
       Task.WaitAll(tasks); 

       foreach (var item in Usage) 
       { 
        Console.WriteLine("{0} - {1}%", item.Key.ProcessName, item.Value); 
       }     
      } 
     } 

     private void DoWork(object o) 
     { 
      Process process = (Process)o; 
      PerformanceCounter pc = new PerformanceCounter("Process", "% Processor Time", process.ProcessName, true); 
      pc.NextValue(); 
      Thread.Sleep(1000); 
      int cpuPercent = (int)pc.NextValue()/Environment.ProcessorCount; 
      if (process == null) 
      { 
       var x = 5; 
      } 
      if (_usage == null) 
      { 
       var t = 6; 
      } 
      _usage.Add(process, cpuPercent); 
     } 
    } 
+1

“问题的第一部分是为什么解决方案有帮助” - 然后请在该问题/答案下的评论中提问。 – 2011-05-07 09:10:53

+0

只是出于好奇,为什么'DoWork'只需要一个'object'参数将它转换成一个'Process',对吗? – 2011-05-07 09:11:18

+0

@亨克 - 已经在评论中提问,但没有回复。 – Johnny 2011-05-07 09:47:13

回答

5

线

_usage.Add(process, cpuPercent); 

从一个线程访问不是线程安全的集合。

使用ConcurrentDictionary<K,V>而不是正常的字典。

的“空引用”的错误仅仅是一个随机的症状,你可以得到其他错误太多。

相关问题