How to stop a running method using keyboard input in a console application in C #?

In short, I use C # for scientific computation, and I wrote a method that has a while loop that can execute with a number of steps given by the user ... Actually this method can take too long to execute (for example, more than 5 hours ) When this takes a long time, I can, for example, stop the method by pressing the Esc key .

As I read something about breaking while , it is as simple as a Boolean flag or something like that. So I thought something like this:

 public Double? Run(int n) { int i = 0; while ((i < n) && (/* inputkey != ConsoleKey.Escape */)) { // here goes the heavy computation thing // and I need to read some "inputkey" as well to break this loop i++; } // I'm not worried about the return statement, as it is easy to do... // returns null if the user skipped the method by pressing Escape // returns null if the method didn't converged // returns the double value that the method calculated otherwise } 

Well, thatโ€™s what Iโ€™m still thinking about ... So, please, could you give some useful ideas in this area? How can I wait for user input (I was thinking about Events , but I'm not sure how to implement it here, and I think this will make the code even slower if I have to listen to the key every time the code step goes to ...

Well, any ideas or comments?


Refresh . I think I would better describe the problem. All the solutions you gave me can solve this problem that I proposed, but I think I was not completely sure of my real problem. I do not know if I should ask another question or continue with this ...

+4
source share
5 answers

You can run this method from a separate thread and set a stop variable when you press a key:

 object myLock = new object(); bool stopProcessing = false; public Double? Run(int n) { int i = 0; while (i < n) { lock(myLock) { if(stopProcessing) break; } // here goes the heavy computation thing // and I need to read some "inputkey" as well to break this loop i++; } } 

and when the key is pressed, update stopProcessing accordingly:

 Console.ReadKey(); lock(myLock) { stopProcessing = true; } 
+4
source

If you just want to stop the application, Ctrl-C from the command line will do this. If you really need to intercept input during a long process, you may need to create a workflow to complete the long process, and then just use the main thread to interact with the console (i.e. Console.ReadLine ()).

+5
source
 using System; using System.Threading.Tasks; namespace ConsoleApplication4 { class Program { static bool _cancelled = false; static void Main( string[] args ) { var computationTask = Task.Factory.StartNew(PerformIncredibleComputation); var acceptCancelKey = Task.Factory.StartNew(AcceptCancel); while (!acceptCancelKey.IsCompleted && ! computationTask.IsCompleted) { computationTask.Wait (100); } if( acceptCancelKey.IsCompleted && !computationTask.IsCompleted ) { computationTask.Wait (new System.Threading.CancellationToken ()); } else if(!acceptCancelKey.IsCompleted) { acceptCancelKey.Wait(new System.Threading.CancellationToken()); } } private static void PerformIncredibleComputation() { Console.WriteLine("Performing computation."); int ticks = Environment.TickCount; int diff = Environment.TickCount - ticks; while (!_cancelled && diff < 10000) { //computing } Console.WriteLine("Computation finished"); } private static void AcceptCancel() { var key = Console.ReadKey(true); Console.WriteLine("Press Esc to cancel"); while(key.Key != ConsoleKey.Escape) { key = Console.ReadKey(true); } _cancelled = true; Console.Write("Computation was cancelled"); } } 

}

+2
source

You will need to do this using threads. When you start a task, create a new thread and execute the task in that thread. Then, in Program.cs, wait for user input. If the user enters something meaningful - in your case, the Esc - warns the background flow of action. The easiest way to do this is to set a static variable. The background thread will check this static variable, and when it is changed, the background thread will clear and interrupt.

See the MSDN article for Threading .

The sample code will be a little deeper, but it will look something like this:

 public class Program.cs { public static myFlag = false; public void Main() { thread = new Thread(new ThreadStart(DoWork)); thread.Start(); Console.ReadLine(); myFlag = true; } public static DoWork() { while(myFlag == false) { DoMoreWork(); } CleanUp() } public static DoMoreWork() { } public static CleanUp() { } } 
+1
source

Console.KeyAvailable on time and take action accordingly.

+1
source

Source: https://habr.com/ru/post/1340648/


All Articles