我有一个非常简单的C#程序(.net 4.5,VS 2013),它使用Winforms运行以获取当前的CPU速度和最大CPU速度并更新以下标签: lblCPUMaxValue and lblCPUCurrentValue
lblCPUMaxValue
lblCPUCurrentValue
我创建了一个名为timerCPUstats的计时器,每隔3000ms计时并调用函数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());
}
问题在于每次标签更新时程序会冻结几秒钟。它基本上变得非互动/冻结。有办法解决这个问题吗?
答案 0 :(得分:2)
您通过在UI线程中执行长时间运行的非UI工作来阻止UI线程。您需要将该工作卸载到另一个线程,然后使用该工作的结果更新UI。
BackgroundWorker
专为此精确操作而设计。计算Result
事件处理程序中的DoWork
并设置该结果,然后使用Result
事件处理程序将RunWorkerCompleted
显示到UI。
另一个选项,如果您使用的是C#5.0,则使用await
,可以让您写一下:
public async void updatePerfInfo()
{
lblCPUMaxValue.Text = await Task.Run(()=>formatMhzGhz(maxCPUSpeed()));
lblCPUCurrentValue.Text = await Task.Run(()=>formatMhzGhz(CPUSpeed()));
}