How to stop a running method with keyboard input in a Console Application on C#?

自作多情 提交于 2019-12-04 07:09:47

You could run this method from a separate thread and set a stop variable when a key is pressed:

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 a key is pressed, update stopProcessing accordingly:

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

If you're just wanting to stop the application, Ctrl-C from the command line will do it. If you really need to intercept input during a long running process, you might want to spawn a worker thread to do the long running process and then just use the main thread to interact with the console (i.e. Console.ReadLine()).

You will need to do this using threading. When you start the task, spawn a new thread and execute the task on that thread. Then in your Program.cs, wait for user input. If the user enters something meaningful - in your case, the Esc key - alert the background thread of the action. The simplest way to do this is by setting a static variable. The background thread will be checking this static variable and when it has been changed, the background thread will clean itself up and abort.

See the MSDN article on Threading.

A code sample will be a little more in depth, but it would 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() { }

}

pool on Console.KeyAvailable in timely manner and take the action accordingly.

Simon Smeets
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");

    }
}

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!