2014-02-10 80 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