如何超时加入到Console.ReadLine()? [英] How to add a Timeout to Console.ReadLine()?
问题描述
我有,我想给用户一个控制台应用程序的 X 的秒响应提示。如果没有输入的一定时间后进行,程序逻辑应该继续。我们假设一个超时是指空响应。
I have a console app in which I want to give the user x seconds to respond to the prompt. If no input is made after a certain period of time, program logic should continue. We assume a timeout means empty response.
什么是处理这个最简单的方法是什么?
What is the most straightforward way of approaching this?
推荐答案
我很惊讶地得知,5年后,所有的答案仍然来自下列一个或多个问题受苦:
I'm surprised to learn that after 5 years, all of the answers still suffer from one or more of the following problems:
- 系统功能比其他的ReadLine使用,导致功能丧失。 (删除/退格/向上键为previous输入)。
- 在功能表现不好的时候多次调用(产卵多线程,多挂的ReadLine的,或其他意外行为)。
- 在功能依赖于忙等待。这是一种可怕的浪费,因为等待预期从若干秒到超时,这可能是多个分钟的任何地方运行。忙等待它运行的时间这样的ammount的是资源,这是特别坏的多线程情况下的一个可怕的吸。如果忙等待的调整,有睡眠这对响应产生负面影响,虽然我承认这可能不是一个大问题。
我相信我的解决方案将解决原来的问题没有从任何上述问题困扰:
I believe my solution will solve the original problem without suffering from any of the above problems:
class Reader {
private static Thread inputThread;
private static AutoResetEvent getInput, gotInput;
private static string input;
static Reader() {
getInput = new AutoResetEvent(false);
gotInput = new AutoResetEvent(false);
inputThread = new Thread(reader);
inputThread.IsBackground = true;
inputThread.Start();
}
private static void reader() {
while (true) {
getInput.WaitOne();
input = Console.ReadLine();
gotInput.Set();
}
}
public static string ReadLine(int timeOutMillisecs) {
getInput.Set();
bool success = gotInput.WaitOne(timeOutMillisecs);
if (success)
return input;
else
throw new TimeoutException("User did not provide input within the timelimit.");
}
}
呼叫,当然,很容易的:
Calling is, of course, very easy:
try {
Console.WriteLine("Please enter your name within the next 5 seconds.");
string name = Reader.ReadLine(5000);
} catch (TimeoutException) {
Console.WriteLine("Sorry, you waited too long.");
}
因此,如何对其他解决方案我提到的那些问题呢?
So how about those problems of the other solutions I mentioned?
- 如你所见,Readline的使用,避免了第一个问题。
- 在该函数的行为正常时多次调用。不管超时是否发生,只有一个背景线程将运行和仅至多一个呼叫的ReadLine将永远被激活。调用该函数将总是导致最新的输入,或超时,用户将不必键入回车不止一次提出自己的意见。
- ,很明显,该功能不依赖于一个忙等待。相反,它使用适当的多线程技术,以prevent资源浪费。
这是我预计这个解决方案的唯一的问题是,它不是线程安全的。然而,多个线程不能真正要求输入用户在同一时间,所以同步应该是拨打电话,以 Reader.ReadLine
反正之前发生的事情。
The only problem that I foresee with this solution is that it is not thread-safe. However, multiple threads can't really ask the user for input at the same time, so synchronization should be happening before making a call to Reader.ReadLine
anyway.
这篇关于如何超时加入到Console.ReadLine()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!