1

可能重复:
如何向 Console.ReadLine() 添加超时?

如果我有一个 Console.ReadKey(),它会使整个程序卡住,我怎样才能让它读取一个密钥 1 秒,如果没有读取一个密钥,则会设置其他内容。

4

3 回答 3

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 回答
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如果一个键被按下并准备好被读取,则返回ReadKeyfalse否则返回。如果没有可用的键,该函数将休眠 50 毫秒,直到它执行下一个循环。这比不睡觉的循环要好,因为这会给你 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 回答
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 回答