Console.ReadKey() がある場合、プログラム全体がスタックします。キーを 1 秒間読み取るようにするにはどうすればよいですか。キーが読み取られない場合は、別のものが設定されます。
3 に答える
コンソールにはプロパティがありますKeyAvailable
。しかし、目的の機能 (タイムアウト) が利用できません。独自の関数を作成できます
private static ConsoleKeyInfo WaitForKey(int ms)
{
int delay = 0;
while (delay < ms) {
if (Console.KeyAvailable) {
return Console.ReadKey();
}
Thread.Sleep(50);
delay += 50;
}
return new ConsoleKeyInfo((char)0, (ConsoleKey)0, false, false, false);
}
この関数は、必要なミリ秒単位の時間が経過するか、キーが押されるまでループします。を呼び出す前に、キーが使用可能かどうかをチェックしますConsole.ReadKey();
。Console.KeyAvailable
キーが使用可能かどうかに関係なく、チェックはすぐに続行されます。true
キーが押され、読み取られる準備ができている場合、またはそれ以外の場合ReadKey
に返されますfalse
。利用可能なキーがない場合、関数は次のループを実行するまで 50 ミリ秒間スリープします。これは、(1 つのコアで) 100% の CPU 使用率が得られるため、スリープせずにループするよりも優れています。
この関数は、ユーザーが押したキーを知りたい場合に備えて、 をConsoleKeyInfo
返します。ReadKey
最後の行は空を作成しますConsoleKeyInfo
( ConsoleKeyInfo 構造体およびConsoleKeyInfo コンストラクターを参照)。ユーザーがキーを押したかどうか、または関数がタイムアウトしたかどうかをテストできます。
if (WaitForKey(1000).KeyChar == (char)0) {
// The function timed out
} else {
// The user pressed a key
}
static ConsoleKeyInfo? MyReadKey()
{
var task = Task.Run(() => Console.ReadKey(true));
bool read = task.Wait(1000);
if (read) return task.Result;
return null;
}
var key = MyReadKey();
if (key == null)
{
Console.WriteLine("NULL");
}
else
{
Console.WriteLine(key.Value.Key);
}
このようなことを意味しますか?
Console.WriteLine("Waiting for input for 10 seconds...");
DateTime start = DateTime.Now;
bool gotKey = false;
while ((DateTime.Now - start).TotalSeconds < 10)
{
if (Console.KeyAvailable)
{
gotKey = true;
break;
}
}
if (gotKey)
{
string s = Console.ReadLine();
}
else
Console.WriteLine("Timed out");