How to interrupt Console.ReadLine

后端 未结 10 787
情歌与酒
情歌与酒 2020-11-28 11:34

Is it possible to stop the Console.ReadLine() programmatically?

I have a console application: the much of the logic runs on a different thread and in th

10条回答
  •  情深已故
    2020-11-28 11:48

    Disclaimer: This is just a copy & paste answer.

    Thanks to Gérald Barré for providing such a great solution:
    https://www.meziantou.net/cancelling-console-read.htm

    Documentation for CancelIoEX:
    https://docs.microsoft.com/en-us/windows/win32/fileio/cancelioex-func

    I tested it on Windows 10. It works great and is way less "hacky" than the other solutions (like reimplementing Console.ReadLine, sending return via PostMessage or closing the handle as in the accepted answer)

    In case the site goes down I cite the code snippet here:

    class Program
    {
        const int STD_INPUT_HANDLE = -10;
    
        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern IntPtr GetStdHandle(int nStdHandle);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CancelIoEx(IntPtr handle, IntPtr lpOverlapped);
    
        static void Main(string[] args)
        {
            // Start the timeout
            var read = false;
            Task.Delay(10000).ContinueWith(_ =>
            {
                if (!read)
                {
                    // Timeout => cancel the console read
                    var handle = GetStdHandle(STD_INPUT_HANDLE);
                    CancelIoEx(handle, IntPtr.Zero);
                }
            });
    
            try
            {
                // Start reading from the console
                Console.WriteLine("Do you want to continue [Y/n] (10 seconds remaining):");
                var key = Console.ReadKey();
                read = true;
                Console.WriteLine("Key read");
            }
            // Handle the exception when the operation is canceled
            catch (InvalidOperationException)
            {
                Console.WriteLine("Operation canceled");
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Operation canceled");
            }
        }
    }
    

提交回复
热议问题