1

重複の可能性:
Console.ReadLine() にタイムアウトを追加するには?

Console.ReadKey() がある場合、プログラム全体がスタックします。キーを 1 秒間読み取るようにするにはどうすればよいですか。キーが読み取られない場合は、別のものが設定されます。

4

3 に答える 3

5

コンソールにはプロパティがあります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
}
于 2013-01-17T18:13:28.550 に答える
5
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);
}
于 2013-01-17T18:22:02.303 に答える
1

このようなことを意味しますか?

    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");
于 2013-01-17T18:08:21.733 に答える