在控制台应用程序中等待键盘事件
Await keyboard event in a Console application
有没有办法在没有专用线程的情况下获得完成的 Task
和 returns 按键?
// Kernel callback, not a new thread in my process waiting for a keyboard event
var key = await KeyPress();
因为 Console.ReadKey()
是一个阻塞调用,只使用一个线程来等待用户输入。
您可以打开标准输入流,其中有读取的异步操作:
using (var stream = Console.OpenStandardInput())
{
var buffer = new byte[1];
var bytesRead = await stream.ReadAsync(buffer, 0, 1);
char c = (char)buffer[0];
Console.WriteLine(c);
}
that is the thing, a thread dedicated only to wait for user input sounds like a waste
(not necessarily a big one, but it feels like it should have an
implementation for this).
对于需要用户输入的控制台应用程序,我不会担心这一点。
无论如何,通过使用一些底层 Win32 API,可能 可以实现您的目标。 ReadConsoleInput
的文档说:
A process can specify a console input buffer handle in one of the wait
functions to determine when there is unread console input. When the
input buffer is not empty, the state of a console input buffer handle
is signaled. To determine the number of unread input records in a
console's input buffer, use the GetNumberOfConsoleInputEvents
function. To read input records from a console input buffer without
affecting the number of unread records, use the PeekConsoleInput
function. To discard all unread records in a console's input buffer,
use the FlushConsoleInputBuffer
function.
因此,理论上,您可以使用 GetStdHandle
返回的句柄并将其传递给
RegisterWaitForSingleObject
. Then you could convert it to an awaitable task using TaskCompletionSource
, e.g. as described here。
这个我没有在实践中验证过。它不应该阻塞线程,但 IMO,再一次,游戏不值得。
有没有办法在没有专用线程的情况下获得完成的 Task
和 returns 按键?
// Kernel callback, not a new thread in my process waiting for a keyboard event
var key = await KeyPress();
因为 Console.ReadKey()
是一个阻塞调用,只使用一个线程来等待用户输入。
您可以打开标准输入流,其中有读取的异步操作:
using (var stream = Console.OpenStandardInput())
{
var buffer = new byte[1];
var bytesRead = await stream.ReadAsync(buffer, 0, 1);
char c = (char)buffer[0];
Console.WriteLine(c);
}
that is the thing, a thread dedicated only to wait for user input sounds like a waste (not necessarily a big one, but it feels like it should have an implementation for this).
对于需要用户输入的控制台应用程序,我不会担心这一点。
无论如何,通过使用一些底层 Win32 API,可能 可以实现您的目标。 ReadConsoleInput
的文档说:
A process can specify a console input buffer handle in one of the wait functions to determine when there is unread console input. When the input buffer is not empty, the state of a console input buffer handle is signaled. To determine the number of unread input records in a console's input buffer, use the
GetNumberOfConsoleInputEvents
function. To read input records from a console input buffer without affecting the number of unread records, use thePeekConsoleInput
function. To discard all unread records in a console's input buffer, use theFlushConsoleInputBuffer
function.
因此,理论上,您可以使用 GetStdHandle
返回的句柄并将其传递给
RegisterWaitForSingleObject
. Then you could convert it to an awaitable task using TaskCompletionSource
, e.g. as described here。
这个我没有在实践中验证过。它不应该阻塞线程,但 IMO,再一次,游戏不值得。