I did not find any of the existing answers completely satisfactory, so I wrote my own to work with TAP and .Net 4.5.
/// <summary> /// Obtains the next character or function key pressed by the user /// asynchronously. The pressed key is displayed in the console window. /// </summary> /// <param name="cancellationToken"> /// The cancellation token that can be used to cancel the read. /// </param> /// <param name="responsiveness"> /// The number of milliseconds to wait between polling the /// <see cref="Console.KeyAvailable"/> property. /// </param> /// <returns>Information describing what key was pressed.</returns> /// <exception cref="TaskCanceledException"> /// Thrown when the read is cancelled by the user input (Ctrl+C etc.) /// or when cancellation is signalled via /// the passed <paramred name="cancellationToken"/>. /// </exception> public static async Task<ConsoleKeyInfo> ReadKeyAsync( CancellationToken cancellationToken, int responsiveness = 100) { var cancelPressed = false; var cancelWatcher = new ConsoleCancelEventHandler( (sender, args) => { cancelPressed = true; }); Console.CancelKeyPress += cancelWatcher; try { while (!cancelPressed && !cancellationToken.IsCancellationRequested) { if (Console.KeyAvailable) { return Console.ReadKey(); } await Task.Delay( responsiveness, cancellationToken); } if (cancelPressed) { throw new TaskCanceledException( "Readkey canceled by user input."); } throw new TaskCanceledException(); } finally { Console.CancelKeyPress -= cancelWatcher; } }
source share