简体   繁体   中英

Correct way to prevent high CPU usage with infinite while loop (Console/Forms hybrid)

I put together a console/forms hybrid program, and to achieve the behavior I was looking for I had to "run" the console in a thread, and then launch the dashboard with another.

I used BackgroundWorker for this. Essentially in the Main method I start the console background worker which in its DoWork block performs a normal while loop to keep a console going. Repetitively checking for input from the console and passing it along to it corresponding action.

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

After the background worker for starting the console is called ie ConsoleBackgroundWorker.RunWorkerAsync() I call a method which performs a loading sequence.

This loading sequence CAN call the second background worker which internally launches the dashboard on a separate thread.

Now the problem I faced was the loop at the end of the load sequence. This loop prevents everything from shutting down until both of the background workers have completed (the forms closed or the console sent a command to shutdown)

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

The problem was CPU usage, it was constantly sitting at 30% and this is without the line you see above System.Threading.Thread.Sleep(10)

My question is, is this ok? and if not what solution do I have? I noticed this did correct the issue, the CPU now rides at 0% when the application is not doing anything. I also haven't seen any performance changes either. But it has not really been "pushed" yet so I couldn't say for sure on the latter observation.

Instead of polling (checking every 10ms, as you've done) the "better" (or at least less CPU intensive) solution would be to use some kind of wait-functions. You could use a ManualResetEvent maybe, or any of the other synchronization objects available in the System.Threading namespace. Depends on what you need. Then you can just call .Wait() on that object and it will block the thread (0% actual CPU usage) until some kind of signal arrives from another thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM