C#Performancecounter冻结了ui

时间:2012-04-06 11:25:59

标签: c# backgroundworker performancecounter

好吧,我的程序中有一个性能计算器来计算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;
    }
}

1 个答案:

答案 0 :(得分:2)

您可以在backgroundworker的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);