简体   繁体   中英

How do I “Pause” a console application when the user presses escape?

I am creating a C# console application that will be performing an infinite process. How can I get the application to "pause" when the user presses the escape key?

Once the user presses the escape key I want the option to either exit the application or continue the loop right where it left off. I don't want any discontinuity in the process. If I press Esc at step 100 I should be able to pick right back up at step 101.

Here is my method so far:

    // Runs the infinite loop application 
    public static void runLoop()
    {
        int count = 0;
        while (Console.ReadKey().Key!= ConsoleKey.Escape)
        {
                WriteToConsole("Doing stuff.... Loop#" + count.ToString());
                for (int step = 0; step <= int.MaxValue; step++ ) {
                    WriteToConsole("Performing step #" + step.ToString());
                    if (step == int.MaxValue)
                    {
                        step = 0; // Re-set the loop counter
                    }
                }


                count++;
        }

        WriteToConsole("Do you want to exit?  y/n");
        exitApplication(ReadFromConsole());
    }

Is there any way to check for the user input key in a separate thread then pause the infinite loop when the other thread sees an Esc key-press?

To find out if there is a key available in the loop, you can do this:

while (someLoopCondition)
{
    //Do lots of work here
    if (Console.KeyAvailable)
    {
        var consoleKey = Console.ReadKey(true);  //true keeps the key from
                                                 //being displayed in the console
        if (consoleKey.Key == ConsoleKey.Escape)
        {
            //Pause here, ask a question, whatever.
        }
    }
}

Console.KeyAvailable returns true if there is a key in the input stream ready to read and it is a non-blocking call so it won't pause to wait for input. You can check if the escape key was pressed and pause or do whatever you want if the condition is true.

Ron, big thank you for your answer. Using Console.KeyAvalible was key to finding the exact solution to my issue. Here is what I did to produce the results I was expecting. I needed to add in a few methods to check if the user wants to break the current operation or start a new loop from the beginning.

    public static void runUpdater()
    {
        int count = 0;
        while (true)
        {
                WriteToConsole("Doing stuff.... Loop# " + count.ToString());
                for (int step = 0; step <= int.MaxValue; step++)
                {
                    if (!breakCurrentOperation())
                    {
                        WriteToConsole("Performing step #" + step.ToString());
                        if (step == int.MaxValue)
                        {
                            step = 0; // Re-set the loop counter
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                count++;


                if (!startNewOperation())
                {
                    // Noop
                }
                else
                {
                    break;
                }

        }

        WriteToConsole("\nAre you ready to run the   database updater again? y/n");
        startApplication(ReadFromConsole());
    }

    public static bool startNewOperation()
    {
        WriteToConsole("Do you want go back to the main menu or start a new update process?  \nType y to start a new update process or n to go to the main menu.");
        string input = ReadFromConsole();

        if (input == "y" || input == "Y")
        {
            return false;
        }
        else if (input == "n" || input == "N")
        {
            return true; // Noop - Restart the Loop from the begining
        }
        else
        {
            WriteToConsole("Error: Input was not recognized. ");
            return startNewOperation(); // Recursivly call method untill user enters a logical input
        }
    }

    public static bool breakCurrentOperation()
    {
        if (Console.KeyAvailable)
        {
            var consoleKey = Console.ReadKey(true);
            if (consoleKey.Key == ConsoleKey.Escape)
            {
                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")
                {
                    return false; // Continue 
                }
                else if (input == "s" || input == "S")
                {
                    return true; // Break the loop
                }
                else
                {
                    WriteToConsole("Error: Input was not recognized, the current process will now continue. Press Esc to stop the operation.");
                }
            }
        }
        return false;
    }

Here are the results:

在此输入图像描述

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