Question

I have a very simple C# program (.net 4.5, VS 2013) that is running using Winforms to grab the current CPU Speed and Max CPU Speed and update the following labels: lblCPUMaxValue and lblCPUCurrentValue

lblCPUMaxValue
lblCPUCurrentValue

I created a timer called timerCPUstats that ticks every 3000ms and calls the function updatePerfInfo():

public uint CPUSpeed()
{
    ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'");
    uint speed = (uint)(Mo["CurrentClockSpeed"]);
    Mo.Dispose();
    return speed;
}

public uint maxCPUSpeed()
{
    ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'");
    uint speed = (uint)(Mo["MaxClockSpeed"]);
    Mo.Dispose();
    return speed;
} 

public string formatMhzGhz(uint mhz)
{
    decimal ghz = (decimal)mhz / 1000;
    ghz = Math.Round(ghz, 2);
    string stringGhz = ghz.ToString() + " GHz";
    return stringGhz;
}

public void updatePerfInfo()
{
    lblCPUMaxValue.Text = formatMhzGhz(maxCPUSpeed());
    lblCPUCurrentValue.Text = formatMhzGhz(CPUSpeed());
}

The problem is that every time the labels update the program freezes for a few seconds. It basically become non interactive / frozen. Is there a way around this?

Was it helpful?

Solution

You're blocking the UI thread by performing long running non-UI work in the UI thread. You need to offload that work to another thread and then update the UI with the results of that work.

A BackgroundWorker is specifically designed for this exact operation. Compute the Result in the DoWork event handler and set that result, then display the Result to the UI using the RunWorkerCompleted event handler.

The other option, if you're using C# 5.0, is to use await, which would let you write:

public async void updatePerfInfo()
{
    lblCPUMaxValue.Text = await Task.Run(()=>formatMhzGhz(maxCPUSpeed()));
    lblCPUCurrentValue.Text = await Task.Run(()=>formatMhzGhz(CPUSpeed()));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top