如何超时加入到Console.ReadLine()? [英] How to add a Timeout to Console.ReadLine()?

查看:417
本文介绍了如何超时加入到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆