while循环导致CPU使用率高,正在检查按键事件

本文关键字:检查 事件 循环 CPU 使用率 while | 更新日期: 2023-09-27 18:22:48

我有一个控制台应用程序,它有两个线程,一个是做重复的耗时工作,另一个是检查用户是否按下了ESC键。如果按下ESC键,则耗时的工作线程将暂停,并显示"确定吗"消息,如果选择"是",则耗时工作线程将完成当前循环,然后退出。

由于while (!breakCurrentOperation(work)) ;循环,我必须检查按键的代码使用了大量CPU资源。我该如何防止这种情况发生?

代码:

    public void runTimeConsumingWork()
    {
        HardWork work = new HardWork();
        Thread workerThread = new Thread(() => work.StartWorking());
        workerThread.Start(); // Start the hard work thread
        while (!workerThread.IsAlive) ; // Hault untill Thread becomes Active 
        // Check if the user wants to stop the hard work
        while (!breakCurrentOperation(work)) ;
        // Cancle the hard work
        work.Stop();
        // Notify the User
        UserInterfaceController.WriteToConsole("Operation Cancled...");
    }

    public static bool breakCurrentOperation(HardWork work)
    {
        if (Console.KeyAvailable)
        {
            var consoleKey = Console.ReadKey(true);
            if (consoleKey.Key == ConsoleKey.Escape)
            {
                work.Pause(); // Pause
                UserInterfaceController.WriteToConsole("Do you want to stop the current process? 'nType s to stop or c to continue.");
                string input = Console.ReadLine();
                if (input == "c" || input == "C")
                {
                    work.Pause(); // Unpause
                    return false; // Continue 
                }
                else if (input == "s" || input == "S")
                {
                    return true; // Break the loop
                }
                else
                {
                    UserInterfaceController.WriteToConsole("Error: Input was not recognized, the current process will now continue. Press Esc to stop the operation.");
                    work.Pause(); // Unpause
                }
            }
        }
        return false;
    }

如果我在主控制台UI线程中放置Thread.Sleep(2000),CPU使用率会下降,但应用程序会延迟2秒而变得没有响应。

while循环导致CPU使用率高,正在检查按键事件

您真的必须不断地轮询输入吗?如果你在一个单独的线程中等待输入,只需使用Console.ReadKey。它会阻止输入线程,但你的另一个线程会继续处理。您似乎没有在输入线程上做任何其他事情,所以阻塞应该不是问题。

由于while循环,您的esc按键检查逻辑在无端循环中运行。因此,该功能将继续利用系统资源。

为了克服这个问题,请使用Thread.Sleep在循环中使用一些延迟。1秒的延迟将大大提高性能。