正确的方法来防止高CPU使用无限while循环(控制台/窗体混合)



我编写了一个控制台/表单混合程序,为了实现我正在寻找的行为,我必须在一个线程中"运行"控制台,然后用另一个线程启动仪表板。

我使用BackgroundWorker。本质上,在Main方法中,我启动了控制台后台工作程序,它在DoWork块中执行正常的while循环以保持控制台运行。重复检查控制台的输入,并将其传递给相应的操作。

while (true && !Program.Shutdown)
{
    String consoleInput = "";
    consoleInput = Program.ReadFromConsole();
    if (String.IsNullOrWhiteSpace(consoleInput))
        continue;
    try
    {
        Program.Shell(consoleInput);
    }
    catch (Exception ex)
    {
        Program.WriteToConsole(ex.Message);
    }
}

在启动控制台的后台工作者被调用之后,即ConsoleBackgroundWorker.RunWorkerAsync(),我调用一个执行加载序列的方法。

这个加载序列可以调用第二个后台工作线程,它在一个单独的线程中内部启动仪表板。

现在我面临的问题是加载序列末尾的循环。这个循环防止一切关闭,直到两个后台工作者都完成(窗体关闭或控制台发送命令关闭)

while (ConsoleBackgroundWorker != null && DashboardBackgroundWorker != null)
{
    /* I'm not sure of how else to fix this. But 
     * this corrects the high CPU usage reported 
     * in the Task Manager. */
    System.Threading.Thread.Sleep(10);
}

问题是CPU使用率,它一直处于30%,这是没有你在上面看到的System.Threading.Thread.Sleep(10)

我的问题是,这样可以吗?如果不是,我有什么解决办法?我注意到这确实纠正了这个问题,当应用程序不做任何事情时,CPU现在以0%的速度运行。我也没有看到任何性能变化。但它还没有真正被"推动",所以我不能肯定地说后一个观察。

比起轮询(每10毫秒检查一次,就像您所做的那样),"更好"(或者至少更少CPU密集)的解决方案是使用某种等待函数。您可以使用ManualResetEvent,或者System.Threading名称空间中可用的任何其他同步对象。这取决于你需要什么。然后你可以在该对象上调用.Wait(),它将阻塞线程(0%实际CPU使用率),直到来自另一个线程的某种信号到达。

最新更新