Reputation: 632
So let's use this code:
Console.ReadKey(true);
//Cancel the ReadKey prompt
Console.WriteLine("ReadKey was cancelled.");
Upon running the program, the only thing that should happen is that the output ReadKey was cancelled.
should appear. How can I achieve this? Is it even possible?
Thanks in advance.
Upvotes: 0
Views: 1429
Reputation: 7111
Nearly 10 years later, how about doing it async
? You still need to do it on another thread if you want to make it cancelable, but...
If you want a fully cancelable async version, here goes:
public static async Task<char?> ReadConsoleCharAsync(CancellationToken cancellationToken, bool intercept = false)
{
// if there is a key available, return it without waiting
// (or dispatching work to the thread queue)
if (Console.KeyAvailable)
{
var read = Console.ReadKey(intercept);
return read.KeyChar;
}
// otherwise
var result = await Task.Run<char?>(async () =>
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(100);
if (Console.KeyAvailable)
{
var read = Console.ReadKey(intercept);
return read.KeyChar;
}
}
cancellationToken.ThrowIfCancellationRequested();
return null;
}, cancellationToken);
return result;
}
I return a char
, but you could return the full ConsoleKeyInfo
if you wanted.
If you want a non-cancellable async
version, it's a bit simpler:
public static async Task<char> ReadConsoleCharAsync(bool intercept = false)
{
// if there is a key available, return it without waiting
// (or dispatching work to the thread queue)
if (Console.KeyAvailable)
{
var read = Console.ReadKey(intercept);
return read.KeyChar;
}
// otherwise
var result = await Task.Run<char>(async () =>
{
while (!Console.KeyAvailable)
{
await Task.Delay(100);
}
var read = Console.ReadKey(intercept);
return read.KeyChar;
});
return result;
}
In both cases, I check to see if there's a character to read before doing anything else. If there is one, I return it. If not, I dispatch work to the threadpool using Task.Run
. I need to return a char?
in the cancellable case; I need to return something when it gets cancelled (so it's a null
)
Upvotes: 0
Reputation: 21
The only way I can see you could do this is using System.Windows.Forms.SendKeys.Send(), however this doesn't work 'out of the box' for a console app because they don't manage windows messages, if you try it you'll see the exception. There could be a way to implement this yourself using windows API's.
Upvotes: 1
Reputation: 485
You can't cancel ReadKey, unless you abort the thread. (Force closing the program.)
I check if a key is available using the Console.KeyAvailable
property before calling ReadKey.
Upvotes: 3