1

CPU 使用率を計算するパフォーマンス カウンターがプログラムに含まれています。それはかなりうまく機能し、バグなどはありません...しかし!performancecounter が読み込まれるたびに UI がフリーズします。

パフォーマンスカウンターをバックグラウンドワーカーにロードするので、UI がフリーズする理由がわかりません...

何か案は?もしそうなら、ありがとう!

コード

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;
    }
}
4

1 に答える 1

2

バックグラウンド ワーカーの DoWork でパフォーマンス カウンターを作成します。しかし、これは単なる創造であり、実際の作業ではありません。コンテンツを からtimerUpdateGUIControls_Tickに移動する必要があります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);
}

ProgressChanged 関数を backgroundworker1 に追加することを忘れないでください。

backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
于 2012-04-06T11:35:46.157 に答える