How to add a Timeout to Console.ReadLine()?

后端 未结 30 2592
耶瑟儿~
耶瑟儿~ 2020-11-22 04:57

I have a console app in which I want to give the user x seconds to respond to the prompt. If no input is made after a certain period of time, program logic should

30条回答
  •  死守一世寂寞
    2020-11-22 05:46

    My code is based entirely on the friend's answer @JSQuareD

    But I needed to use Stopwatch to timer because when I finished the program with Console.ReadKey() it was still waiting for Console.ReadLine() and it generated unexpected behavior.

    It WORKED PERFECTLY for me. Maintains the original Console.ReadLine ()

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("What is the answer? (5 secs.)");
            try
            {
                var answer = ConsoleReadLine.ReadLine(5000);
                Console.WriteLine("Answer is: {0}", answer);
            }
            catch
            {
                Console.WriteLine("No answer");
            }
            Console.ReadKey();
        }
    }
    
    class ConsoleReadLine
    {
        private static string inputLast;
        private static Thread inputThread = new Thread(inputThreadAction) { IsBackground = true };
        private static AutoResetEvent inputGet = new AutoResetEvent(false);
        private static AutoResetEvent inputGot = new AutoResetEvent(false);
    
        static ConsoleReadLine()
        {
            inputThread.Start();
        }
    
        private static void inputThreadAction()
        {
            while (true)
            {
                inputGet.WaitOne();
                inputLast = Console.ReadLine();
                inputGot.Set();
            }
        }
    
        // omit the parameter to read a line without a timeout
        public static string ReadLine(int timeout = Timeout.Infinite)
        {
            if (timeout == Timeout.Infinite)
            {
                return Console.ReadLine();
            }
            else
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
    
                while (stopwatch.ElapsedMilliseconds < timeout && !Console.KeyAvailable) ;
    
                if (Console.KeyAvailable)
                {
                    inputGet.Set();
                    inputGot.WaitOne();
                    return inputLast;
                }
                else
                {
                    throw new TimeoutException("User did not provide input within the timelimit.");
                }
            }
        }
    }
    

提交回复
热议问题