2012-02-29 18 views
13

私のマルチスレッドアプリケーション(マルチコアプロセッサで動作)のCPU使用率を表示します。タスクマネージャの近くにある番号を受け取りたいしかし、私は100%以上の数字を得ました。さらに500%以上。はい、私は知っている、カウンター「%プロセッサ時間」よりもカテゴリ「プロセス」のために私は(私の設定のために同じ)Environment.ProcessorCountまたは「NumberOfLogicalProcessors」に分割する必要があります。この操作の後、500%が結果になります。ハードウェア(i7、i5、Core2)とソフトウェア構成(Windows 7 SP1のすべての更新プログラム、Windows 2008 R2 SP1のすべての更新プログラム)の異なるコンピュータでこの例をテストしたところ、同じ問題が発生しました。現在のプロセスのパフォーマンスカウンタのCPU使用率が100を超えています

public static class SystemInfo 
{ 
    private static Process _thisProc; 
    private static bool HasData = false; 
    private static PerformanceCounter _processTimeCounter; 

    private static void Init() 
    { 
     if (HasData) 
      return; 

     if (CheckForPerformanceCounterCategoryExist("Process")) 
     { 
      _processTimeCounter = new PerformanceCounter(); 
      _processTimeCounter.CategoryName = "Process"; 
      _processTimeCounter.CounterName = "% Processor Time"; 
      _processTimeCounter.InstanceName = FindInstanceName("Process"); 
      _processTimeCounter.NextValue(); 
     } 

     MaximumCpuUsageForCurrentProcess = 0; 
     HasData = true; 
    } 

    private static bool CheckForPerformanceCounterCategoryExist(string categoryName) 
    { 
     return PerformanceCounterCategory.Exists(categoryName); 
    } 

    public static string FindInstanceName(string categoryName) 
    { 
     string result = String.Empty; 
     _thisProc = Process.GetCurrentProcess(); 

     if (!ReferenceEquals(_thisProc, null)) 
     { 
      if (!String.IsNullOrEmpty(categoryName)) 
      { 
       if (CheckForPerformanceCounterCategoryExist(categoryName)) 
       { 
        PerformanceCounterCategory category = new PerformanceCounterCategory(categoryName); 
        string[] instances = category.GetInstanceNames(); 
        string processName = _thisProc.ProcessName; 

        if (instances != null) 
        { 
         foreach (string instance in instances) 
         { 
          if (instance.ToLower().Equals(processName.ToLower())) 
          { 
           result = instance; 
           break; 
          } 
         } 
        } 
       } 
      } 
     } 
     return result; 
    } 

    public static int CpuUsageForCurrentProcess 
    { 
     get 
     { 
      Init(); 

      if (!ReferenceEquals(_processTimeCounter, null)) 
      { 
       int result = (int) _processTimeCounter.NextValue(); 
       result /= Environment.ProcessorCount; //NumberOfLogicalProcessors //same for me 

       if (MaximumCpuUsageForCurrentProcess < result) 
        MaximumCpuUsageForCurrentProcess = result; 

       return result; 
      } 
      return 0; 
     } 
    } 

    public static int MaximumCpuUsageForCurrentProcess { private set; get; } 
} 

および実行するコード(あなたがウィンドウを作成する必要がある2つのlabeles、1つのBackgroundWorkerのとボタン一つでアプリケーションを形成する)

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     IList<Task> tasks = new List<Task>(); 
     for (int i = 0; i < 10; i++) 
     { 
      Task t = new Task(() => 
      { 
       do { 
        if (backgroundWorker1.CancellationPending) 
         break; 
       } while (true); 
      }); 
      t.Start(); 
      tasks.Add(t); 
     } 

     Task displayProgress = new Task(() => { do { 
                if (backgroundWorker1.CancellationPending) 
                 break; 
                backgroundWorker1.ReportProgress(1); 
                Thread.Sleep(10); 
               } while (true); }); 
     displayProgress.Start(); 
     tasks.Add(displayProgress); 

     Task.WaitAll(tasks.ToArray()); 
    } 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     label1.Text = SystemInfo.CpuUsageForCurrentProcess.ToString(); 
     label2.Text = SystemInfo.MaximumCpuUsageForCurrentProcess.ToString(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     label1.Text = SystemInfo.CpuUsageForCurrentProcess.ToString(); 

     if (backgroundWorker1.IsBusy) 
      backgroundWorker1.CancelAsync(); 
     else 
      backgroundWorker1.RunWorkerAsync(); 
    } 

私に私のエラーを表示してください。そして、はい、私はthis articleを読み、それがのCPU使用率を集計しているため

「\プロセス(...)\%プロセッサ時間は」(NはCPUの数である)N * 100まで行くことができることに気づきましたすべてのCPUで要求されたプロセス

+1

穴のコードを質問にコピーしないでください。質問に答えるために必要な行だけを入力してください。もちろん、あなたのコードにいくつかのコメントを残してください。 –

答えて

4

This(幾分関連)問題は、低オーバーヘッドと簡単に実装するために、代わりSystem.Diagnostics.Process.TotalProcessorTimeSystem.Diagnostics.ProcessThread.TotalProcessorTimeプロパティを使用して示唆しています。

:あなたはへの呼び出しの間で十分な長待っていないように(編集。同様に、プロパティを使用する方法を説明するHere's an article)また

は、それが見えます「_processTimeCounter.NextValue()。」 the documentationによれば、あなたは少なくとも1秒待つことになっています。それがあなたの奇妙な数字を引き起こすかどうかは分かりません。

+0

2つのカウンター読み取りに応じて、カウンターの呼び出しに必要な1秒の遅延が異なります。しかし、このソリューションは私のコードでうまく動作します。 System.Diagnostics.ProcessThread.TotalProcessorTimeについて、以前はこのソリューションを使用しようとしましたが、奇妙なCPU負荷(実際のプロセス負荷を表示しない<10%)がありました。 – user809808

+0

あなたが言及した記事は完全な混乱です:サンプルプログラムは、いくつかの負の値を表示します。計算自体は、未知のための "アイドル"プロセスのためのカウンターを含む。私はそれほど誤解を招くような情報は見たことがありません。いくつかの答えがこの記事に言及するのは、基本的には失望していることです。 – alehro

関連する問題