2015-10-15 27 views
6

Sto creando un'applicazione console C# che eseguirà un processo infinito. Come posso mettere l'applicazione in "pausa" quando l'utente preme la chiave di escape?Come si "sospende" un'applicazione della console quando l'utente preme escape?

Una volta che l'utente preme il tasto di escape, voglio che l'opzione esca dall'applicazione o continui il ciclo nel punto in cui era stata interrotta. Non voglio alcuna discontinuità nel processo. Se premo Esc al passo 100 dovrei essere in grado di raccogliere a destra indietro fino al punto 101.

Ecco il mio metodo finora:

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

C'è un modo per verificare la chiave input dell'utente in un thread separato quindi mette in pausa il ciclo infinito quando l'altro thread vede un tasto Esc premuto?

+0

Certo, ma si sta andando ad avere per entrare nella filettatura. – BradleyDotNET

+0

Quindi quello che stai cercando è un modo per controllare che la chiave di escape venga premuta, ma senza che il ciclo attenda l'input dell'utente, giusto? –

+1

Hmm, piuttosto improbabile che l'utente possa mai capire di premere questo tasto senza un manuale. Premerà invece Ctrl + S, senza bisogno di aiuto. –

risposta

9

per verificare se v'è una chiave disponibile nel ciclo, si può fare questo:

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 ritorna true se c'è una chiave nel flusso di input pronto a leggere ed è un non- bloccando la chiamata in modo che non si fermi per attendere l'input. Puoi controllare se il tasto Esc è stato premuto e mettere in pausa o fare quello che vuoi se la condizione è vera.

0

Ron, grande grazie per la risposta. L'utilizzo di Console.KeyAvalible è stato fondamentale per trovare la soluzione esatta al mio problema. Ecco cosa ho fatto per produrre i risultati che mi aspettavo. Avevo bisogno di aggiungere alcuni metodi per verificare se l'utente desidera interrompere l'operazione corrente o avviare un nuovo ciclo dall'inizio.

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

Ecco i risultati:

enter image description here