栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何将超时添加到Console.ReadLine()?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何将超时添加到Console.ReadLine()?

令我惊讶的是,五年后,所有答案仍然遭受以下一个或多个问题的困扰:

  • 使用ReadLine以外的功能,会导致功能丧失。(删除/退格/上一个键用于上一个输入)。
  • 多次调用时,函数的行为不佳(产生多个线程,许多吊挂的ReadLine或其他意外行为)。
  • 功能依赖于繁忙等待。这是一个可怕的浪费,因为等待可能会在几秒到超时之间的任何地方运行,超时可能是数分钟。如此长时间的繁忙等待是对资源的可怕吸收,在多线程方案中尤其如此。如果将忙碌等待更改为睡眠,这会对响应性产生负面影响,尽管我承认这可能不是一个大问题。

我相信我的解决方案将解决原来的问题,而不会遇到上述任何问题:

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();    }  }  // omit the parameter to read a line without a timeout  public static string ReadLine(int timeOutMillisecs = Timeout.Infinite) {    getInput.Set();    bool success = gotInput.WaitOne(timeOutMillisecs);    if (success)      return input;    else      throw new TimeoutException("User did not provide input within the timelimit.");  }}

当然,调用非常简单:

try {  Console.WriteLine("Please enter your name within the next 5 seconds.");  string name = Reader.ReadLine(5000);  Console.WriteLine("Hello, {0}!", name);} catch (TimeoutException) {  Console.WriteLine("Sorry, you waited too long.");}

另外,您可以使用

TryXX(out)
约定,如shmueli所建议:

  public static bool TryReadLine(out string line, int timeOutMillisecs = Timeout.Infinite) {    getInput.Set();    bool success = gotInput.WaitOne(timeOutMillisecs);    if (success)      line = input;    else      line = null;    return success;  }

称为如下:

Console.WriteLine("Please enter your name within the next 5 seconds.");string name;bool success = Reader.TryReadLine(out name, 5000);if (!success)  Console.WriteLine("Sorry, you waited too long.");else  Console.WriteLine("Hello, {0}!", name);

在这两种情况下,您都无法将呼叫

Reader
与普通
Console.ReadLine
呼叫混在一起:如果
Reader
超时,将会有一个挂断的
ReadLine
呼叫。相反,如果您要进行普通(非定时)
ReadLine
呼叫,只需使用
Reader
并忽略超时,以便它默认为无限超时。

那么我提到的其他解决方案的那些问题呢?

  • 如您所见,使用ReadLine可以避免第一个问题。
  • 多次调用该函数时,其行为正常。无论是否发生超时,都只会运行一个后台线程,并且最多只能激活一次对ReadLine的调用。调用该函数将始终导致最新输入或超时,并且用户无需多次按下Enter键即可提交输入。
  • 而且,显然,该功能不依赖于繁忙等待。相反,它使用适当的多线程技术来防止浪费资源。

我预见到该解决方案的唯一问题是它不是线程安全的。但是,多个线程实际上并不能同时要求用户输入,因此

Reader.ReadLine
无论如何都要在调用之前进行同步。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/430476.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号