【发布时间】:2015-10-12 04:55:42
【问题描述】:
我需要每 20 秒做一些后台工作(它不必正好是 20000 毫秒,我可以允许延迟)。 我正在使用执行该函数的 Backgroundworker,然后使用 Timer 再等待 20 秒:
private readonly BackgroundWorker Worker = new BackgroundWorker();
volatile bool keepWorkerRunning;
Worker.DoWork += Worker_DoWork;
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 20000;
aTimer.Enabled = true;
keepWorkerRunning = true;
while (keepWorkerRunning) ;
aTimer.Enabled = false;
}
该工作器在软件运行期间一直处于活动状态。
问题是它占用了大部分 CPU。我注意到我的软件一直在使用大约 70% 的 CPU,只是停用 Backgroundworker,CPU 使用率下降到 0.5%。
如何在不使 CPU 过载的情况下完成相同的工作?
【问题讨论】:
-
为什么要同时使用定时器和BackgroundWorker?您可以在单个计时器的
Tick处理程序中执行您想做的事情,该计时器每 20 秒计时一次。此外,CPU 使用率的原因可能不是 BackgroundWorker/Timer 构造,而是您的繁忙循环 (while(true)) -
我记得从以前的一些帖子或答案中复制了这个结构。它完全可以完成我需要的工作,但它需要太多的 CPU 能力。您是否有其他需要更少的替代解决方案?请注意,它必须在与 UI 不同的线程上完成。
-
如果您真的想采用该解决方案,请将
while(keepWorkerRunning);替换为while(keepWorkerRunning) { Threading.Thread.Sleep(100); }之类的东西,以摆脱占用全部 CPU 资源的繁忙循环。 -
扔掉 BackgroundWorker 并在 Timer 的 Elapsed 处理程序中执行后台工作,该处理程序在 ThreadPool 线程上运行。有关 Times.Timer 和 Threading.Timer 之间的区别,请参阅this question。
-
@LInsoDeTeh,
Thread.Sleep(100)对于那些王者来说是一个非常糟糕的解决方案。请不要这样做,也不要建议其他人这样做。
标签: c# wpf backgroundworker system.timers.timer