首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#图形用户界面在通过计时器更新标签时冻结

C#图形用户界面在通过计时器更新标签时冻结
EN

Stack Overflow用户
提问于 2014-02-10 15:27:02
回答 1查看 1.9K关注 0票数 0

我有一个非常简单的C#程序(.net 4.5,VS 2013),它使用Winforms获取当前的CPU速度和最大CPU速度,并更新以下标签:

代码语言:javascript
复制
lblCPUMaxValue
lblCPUCurrentValue

我创建了一个名为timerCPUstats的计时器,它每3000 the计时一次,并调用函数updatePerfInfo():

代码语言:javascript
复制
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());
}

问题是每次标签更新程序都会冻结几秒钟。它基本上变成了非交互/冻结。有办法绕道吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-10 15:32:33

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

BackgroundWorker是专门为这个精确的操作而设计的。在Result事件处理程序中计算DoWork并设置结果,然后使用RunWorkerCompleted事件处理程序将Result显示给UI。

如果您使用的是C# 5.0,则另一个选项是使用await,这将允许您编写:

代码语言:javascript
复制
public async void updatePerfInfo()
{
    lblCPUMaxValue.Text = await Task.Run(()=>formatMhzGhz(maxCPUSpeed()));
    lblCPUCurrentValue.Text = await Task.Run(()=>formatMhzGhz(CPUSpeed()));
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21681174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档