2014-02-10 43 views
0

我有一个非常简单的C#程序(.NET 4.5,VS 2013)正在使用的WinForms抓住当前的CPU速度和最大CPU速度和更新下列标签运行: lblCPUMaxValue and lblCPUCurrentValueC#GUI冻结当更新标签通过定时器

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()); 
} 

的问题是,每一个标签更新程序时几秒钟冻结。它基本上变成了非交互/冻结。有没有解决的办法?

+1

您是否正在运行的WinForms? WPF?您的UI冻结,因为更新UI的相同线程也在运行计算。旋转背景工作者来处理这个问题是适当的。 – paqogomez

回答

2

您通过在UI线程中执行长时间运行的非UI工作来阻止UI线程。您需要将该工作卸载到另一个线程,然后使用该工作的结果更新UI。

A BackgroundWorker是专门为此准确操作而设计的。计算DoWork事件处理函数中的Result并设置该结果,然后使用RunWorkerCompleted事件处理函数将Result显示到UI。

另一种选择,如果你使用C#5.0,是使用await,这将让你写:

public async void updatePerfInfo() 
{ 
    lblCPUMaxValue.Text = await Task.Run(()=>formatMhzGhz(maxCPUSpeed())); 
    lblCPUCurrentValue.Text = await Task.Run(()=>formatMhzGhz(CPUSpeed())); 
} 
+0

我正在使用C#5.0,因此,等待是完美的。我尝试了背景工作并迷路了,但我可能会想出来。谢谢! – imthatguyhere