2012-04-06 4 views
0

申し訳ありませんが、私は自分のプログラムでCPU使用量を計算するパフォーマンスカウンターを持っています。それはかなりうまく動作し、バグはありません...しかし、!私のUIは、パフォーマンスカウンタが読み込まれるたびにフリーズします。C#Performancecounterフリーズui

私はそれがUIを凍結だ理由は分からないので、私はBackgroundWorkerのでperformancecounterをロード...

任意のアイデアは?もしそうなら、ありがとう!

コード

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 
     try 
     { 
      SetPerformanceCounters(); 
      timerUpdateGUIControls.Start(); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex); 
     } 
    } 

    private void SetPerformanceCounters() 
    { 
     performanceCounterCPU.CounterName = "% Processor Time"; 
     performanceCounterCPU.CategoryName = "Processor"; 
     performanceCounterCPU.InstanceName = "_Total"; 

     performanceCounterRAM.CounterName = "% Committed Bytes In Use"; 
     performanceCounterRAM.CategoryName = "Memory"; 
    } 
    private void timerUpdateGUIControls_Tick(object sender, EventArgs e) 
    { 
     try 
     { 
      SystemStatusprogressbarCPU.Value = (int)(performanceCounterCPU.NextValue()); 
      SystemStatuslabelCPU.Text = "CPU: " + SystemStatusprogressbarCPU.Value.ToString(CultureInfo.InvariantCulture) + "%"; 

      var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB(); 
      var tot = PerformanceInfo.GetTotalMemoryInMiB(); 
      var percentFree = ((decimal)phav/tot) * 100; 
      var percentOccupied = 100 - percentFree; 
      SystemStatuslabelRAM.Text = "RAM: " + (percentOccupied.ToString(CultureInfo.InvariantCulture) + "%").Remove(2, 28); 
      SystemStatusprogressbarRAM.Value = Convert.ToInt32((percentOccupied)); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex); 
     } 
    } 

RAM値の低いものを取得するクラス:

public static class PerformanceInfo 
{ 
    [DllImport("psapi.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool GetPerformanceInfo([Out] out PerformanceInformation PerformanceInformation, 
               [In] int Size); 

    [StructLayout(LayoutKind.Sequential)] 
    public struct PerformanceInformation 
    { 
     public int Size; 
     public IntPtr CommitTotal; 
     public IntPtr CommitLimit; 
     public IntPtr CommitPeak; 
     public IntPtr PhysicalTotal; 
     public IntPtr PhysicalAvailable; 
     public IntPtr SystemCache; 
     public IntPtr KernelTotal; 
     public IntPtr KernelPaged; 
     public IntPtr KernelNonPaged; 
     public IntPtr PageSize; 
     public int HandlesCount; 
     public int ProcessCount; 
     public int ThreadCount; 
    } 

    public static Int64 GetPhysicalAvailableMemoryInMiB() 
    { 
     var pi = new PerformanceInformation(); 
     if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi))) 
     { 
      return Convert.ToInt64((pi.PhysicalAvailable.ToInt64() * pi.PageSize.ToInt64()/1048576)); 
     } 
     return -1; 
    } 

    public static Int64 GetTotalMemoryInMiB() 
    { 
     var pi = new PerformanceInformation(); 
     if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi))) 
     { 
      return Convert.ToInt64((pi.PhysicalTotal.ToInt64() * pi.PageSize.ToInt64()/1048576)); 
     } 
     return -1; 
    } 
} 
+1

いくつかのコードが役立つだろう... – RvdK

+0

@PoweRoyいやああ、申し訳ありません。コードを追加しました。 –

答えて

2

あなたはBackgroundWorkerののDoWorkでパフォーマンスカウンタを作成します。しかしこれは創造であり、実際の仕事ではありません。あなたがbackgroundworker1にProgressChanged機能を追加することを忘れないでくださいbackgroundWorker1_DoWork

struct SystemStatus 
{ 
    public int CpuLoad; 
    public decimal OccupiedPercentage; 
} 

private void SetPerformanceCounters() 
{ 
    performanceCounterCPU.CounterName = "% Processor Time"; 
    performanceCounterCPU.CategoryName = "Processor"; 
    performanceCounterCPU.InstanceName = "_Total"; 

    performanceCounterRAM.CounterName = "% Committed Bytes In Use"; 
    performanceCounterRAM.CategoryName = "Memory"; 
} 

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
{ 
    try 
    { 
     SetPerformanceCounters();  

     while (!backgroundWorker1.CancellationPending) 
     { 
      SystemStatus status = new SystemStatus(); 
      status.CpuLoad = (int)(performanceCounterCPU.NextValue())  

      var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB(); 
      var tot = PerformanceInfo.GetTotalMemoryInMiB(); 
      var percentFree = ((decimal)phav/tot) * 100; 
      status.OccupiedPercentage = 100 - percentFree; 

      backgroundWorker1.ReportProgress(0, status); 

      Thread.Sleep(500); //set update frequency to 500ms 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex); 
    } 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    SystemStatus status = e.UserState as SystemStatus; 

    SystemStatusprogressbarCPU.Value = status.CpuLoad; 
    SystemStatuslabelCPU.Text = "CPU: " + Sstatus.CpuLoad.ToString(CultureInfo.InvariantCulture) + "%"; 

    SystemStatuslabelRAM.Text = "RAM: " + (status.OccupiedPercentage.ToString(CultureInfo.InvariantCulture) + "%").Remove(2, 28); 
    SystemStatusprogressbarRAM.Value = Convert.ToInt32(status.OccupiedPercentage); 
} 

timerUpdateGUIControls_Tickから内容を移動する必要があります

backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 
+0

しかし、backgruondworkerに入っている場合、どのように 'timerUpdateGUIControls_Tick'からコンテンツを500msごとに更新するのですか? –

+0

Thread.Sleepします。 – RvdK

+0

岡井、私は、これを使ってラベルとプログレスバーのクロススレッドを更新しようとしています: 'Invoke((MethodInvoker) デリゲート {/ *コード* /});'でもUIはまだ*フリーズしています。 (それは今白くなっているとしよう:o)。 –

関連する問題