2014-06-09 3 views
9

이는 유치원 1에 뭘 메신저입니다 :항상 0 %의 CPU 사용률을 얻는 이유는 무엇입니까?

void PopulateApplications() 
{ 
    DoubleBufferedd(dataGridView1, true); 

    int rcount = dataGridView1.Rows.Count; 
    int rcurIndex = 0; 

    foreach (Process p in Process.GetProcesses()) 
    { 
     try 
     { 
      if (File.Exists(p.MainModule.FileName)) 
      { 
       memoryUsage = Core.getallmemoryusage(p.ProcessName); 
       Core.getcpu(p.ProcessName); 
       cpuusage = Core.processes; 

       var icon = Icon.ExtractAssociatedIcon(p.MainModule.FileName); 
       Image ima = icon.ToBitmap(); 
       ima = resizeImage(ima, new Size(25, 25)); 
       ima = (Image)(new Bitmap(ima, new Size(25, 25))); 
       String status = p.Responding ? "Running" : "Not Responding"; 

       if (rcurIndex < rcount - 1) 
       { 
        var currentRow = dataGridView1.Rows[rcurIndex]; 
        currentRow.Cells[0].Value = ima; 
        currentRow.Cells[1].Value = p.ProcessName; 
        currentRow.Cells[2].Value = cpuusage; 
        currentRow.Cells[3].Value = memoryUsage; 
        currentRow.Cells[4].Value = status; 
       } 
       else 
       { 
        dataGridView1.Rows.Add(ima, p.ProcessName,cpuusage,memoryUsage, status);//false, ima, p.ProcessName, status); 
       } 

       rcurIndex++; 
      } 
     } 
     catch (Exception e) 
     { 
      string t = "error"; 
     } 
    } 

    if (rcurIndex < rcount - 1) 
    { 
     for (int i = rcurIndex; i < rcount - 1; i++) 
     { 
      dataGridView1.Rows.RemoveAt(rcurIndex); 
     } 
    } 
} 

지금 Form1에 PopulateApplications의 방법은, 내가 타이머 틱 이벤트 각 오초에서 호출. 그런 다음 프로세스마다 매번 루프를 실행하고 메모리 사용량과 CPU 사용량을 확인합니다. 이 코드는 Core 클래스의 메모리 및 CPU 방법입니다.

메모리 방법에는 문제가 없습니다. 좋은 일을 빨리.

public static string getallmemoryusage(string processName) 
{ 
    var counter = new PerformanceCounter("Process", "Working Set - Private", processName); 
    privateMemeory = (counter.NextValue()/1024/1024).ToString(); 
    //string.Format("Private memory: {0}k", counter.NextValue()/1024/1024); 
    return privateMemeory;   
} 

문제는 getcpu 방법입니다. 나는 CPU 사용량을 얻기 위해 1000ms마다 잠을 자도록해야한다. 이 메서드에 중단 점을 사용하면 결국 값을 가져옵니다. 문제는 form1에서 메서드를 호출 할 때마다 5 초마다 호출되며이 작업은 매 5 초마다 getcpu이고 스레드가 잠자기 상태 일 때 매우 느리게 작동합니다. 스레드를 10ms로 설정하면 속도는 빠르지 만 대부분의 프로세스에서는 0 % 또는 100 % 사용량을 얻게됩니다.

public static string getcpu(string name) 
{ 
    var cpuload = new PerformanceCounter("Processor", "% Processor Time", "_Total"); 

    processes = Convert.ToInt32(cpuload.NextValue()) + "%"; 
    System.Threading.Thread.Sleep(1000); 

    processes = cpuload.NextValue() + "%"; 
    System.Threading.Thread.Sleep(1000); 

    processes = cpuload.NextValue() + "%"; 
    System.Threading.Thread.Sleep(1000); 

    processes = cpuload.NextValue() + "%"; 
    System.Threading.Thread.Sleep(1000); 

    processes = cpuload.NextValue() + "%"; 
    System.Threading.Thread.Sleep(1000); 

    return processes; 
} 
+0

로템 오른쪽 : 그래서 여러 프로세스에 대한 당신은 그런 방법을 가질 수 있습니다. 아직도 나는 모든 과정에서 0 %를 얻는다. 예를 들어, 테스트 목록에서 나는 1 개의 인덱스와 : chorme CPU0 %를 볼 수 있으며 모든 프로세스에 대해 동일합니다. – user3681442

+0

getcpu 메소드에서 예외를 얻지는 않습니다. 예외를 추가하고 시도를 추가했습니다. 하지만 form1에서는 일부 프로세스에서 예외가 발생하지만 거부 된 액세스는 시스템 프로세스이므로 액세스가 거부 될 염려는 없습니다. – user3681442

+0

방금 ​​메모리 사용량 부분이 아무 문제없이 작동하고 있음을 보여주는 질문을 다시 업데이트했습니다. 여전히 CPU 사용량이 작동하지 않습니다. – user3681442

답변

6

% Processor Time 측정 상기 Thread.Sleep(1000).NextValue()는 통화 시간을 결정하기 때문에 필요하며, 상기 프로세서는 .NextValue()에 대한 최근의 콜 이후 사용 하였다. 이 계산에 대한 자세한 내용은 http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx을 확인하십시오.

1) 프로세스의 이름으로 전달되기 때문에, 당신이 단일 프로세스의 프로세서 시간을 측정 할 가정

제안의 몇

. 그러나 메소드 내에서 해당 매개 변수를 사용하지 않으므로 대신 전반적인 평균 시스템 프로세서 시간을 측정하고 있습니다. 카운터 범주에 대한 "Processor""Process"의 차이를 마음하시기 바랍니다

public static double GetCpuUsage(Process process) 
{ 
    PerformanceCounter cpuCounter = new PerformanceCounter(); 

    cpuCounter.CategoryName = "Process"; 
    cpuCounter.InstanceName = process.ProcessName; 
    cpuCounter.CounterName = "% Processor Time"; 

    // The first call will always return 0 
    cpuCounter.NextValue(); 
    // That's why we need to sleep 1 second 
    Thread.Sleep(1000); 
    // The second call determines, the % of time that the monitored process uses on 
    // % User time for a single processor. 
    // So the limit is 100% * the number of processors you have. 
    double processorUsagePercent = cpuCounter.NextValue(); 

    // Hence we need to divide by the number of processors to get the average CPU usage of one process during the time measured 
    return processorUsagePercent/Environment.ProcessorCount; 
} 

: 당신은 하나 개의 프로세스에 대한 성능을 측정하려면

그래서, 당신은 같은 것을 사용할 수 있습니다.

2) .NextValue() 번을 연속적으로 여러 번 호출 한 다음 마지막 값만 반환하는 이유는 무엇입니까? 그것은 당신의 방법을 너무 느리게 만듭니다. 위의 예제에 표시된 두 가지 계산으로 충분합니다.

3) 여러 프로세스를 모니터링하려는 경우 .NextValue()에 대한 모든 호출 사이에 1 초를 기다릴 필요가 없습니다. 특정 카운터에서 .NextValue()을 마지막으로 호출 한 후 최소 1 초가 경과했는지 확인해야합니다. 내가 이름 변수와 메신저 번만 Form1에 다시 모든 프로세스에 itertiing하지를 사용하여 업데이트 getcpu 방법으로 내 질문을 변경

public static Dictionary<Process, double> GetCpuUsages(Process[] processes) 
{ 
    // One performance counter is required per process 
    PerformanceCounter[] counters = new PerformanceCounter[processes.Length]; 

    // Instantiate a new counter per process 
    for(int i = 0; i < processes.Length; i++) 
    { 
     PerformanceCounter processorTimeCounter = new PerformanceCounter(
      "Process", 
      "% Processor Time", 
      processes[i].ProcessName); 
     // Call NextValue once to have a reference value 
     processorTimeCounter.NextValue(); 
     // Add it to the array 
     counters[i] = processorTimeCounter; 
    } 

    // Sleep one second to have accurate measurement 
    Thread.Sleep(1000); 
    // Here we store the processes along with their measurement in a dictionary 
    Dictionary<Process, double> cpuUsageDictionary = new Dictionary<Process, double>(); 

    for (int i = 0; i < counters.Length; i++) 
    { 
     // Determine CPU usage and divide by the number of cores 
     double cpuUsage = counters[i].NextValue()/Environment.ProcessorCount; 
     // And now we add one key/value pair per process along with its cpu time measurement 
     cpuUsageDictionary.Add(processes[i], cpuUsage); 
    } 

    return cpuUsageDictionary; 
} 
관련 문제