如何向Console.ReadLine()添加超時?我有一個控制臺應(yīng)用程序,我想在其中給用戶x秒來響應(yīng)提示符。如果在一段時間后沒有輸入,則程序邏輯應(yīng)該繼續(xù)。我們假設(shè)超時意味著空響應(yīng)。最直截了當?shù)姆椒ㄊ鞘裁矗?
3 回答

MM們
TA貢獻1886條經(jīng)驗 獲得超2個贊
使用的是ReadLine以外的函數(shù),導(dǎo)致功能丟失。(刪除/退格/向上鍵用于先前的輸入)。 函數(shù)在多次調(diào)用(產(chǎn)生多個線程、許多掛起的ReadLine或其他意外行為)時表現(xiàn)不好。 函數(shù)依賴于繁忙的等待。這是一種可怕的浪費,因為等待被期望在任何地方運行,從幾秒鐘到超時,這可能是多分鐘。一個繁忙的等待,跑了這么長的時間,是一個可怕的吸資源,這是特別糟糕的多線程場景。如果用睡眠來修改繁忙-等待,這會對響應(yīng)性產(chǎn)生負面影響,盡管我承認這可能不是什么大問題。
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)
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,避免了第一個問題。 該函數(shù)在多次調(diào)用時運行正常。不管是否發(fā)生超時,只有一個后臺線程將運行,并且最多只有一個對ReadLine的調(diào)用將是活動的。調(diào)用函數(shù)總是會導(dǎo)致最新的輸入,或者超時,用戶不必多次按Enter鍵才能提交輸入。 而且,很明顯,這個函數(shù)不依賴于繁忙的等待。相反,它使用適當?shù)亩嗑€程技術(shù)來防止資源浪費。
Reader.ReadLine

達令說
TA貢獻1821條經(jīng)驗 獲得超6個贊
string ReadLine(int timeoutms){ ReadLineDelegate d = Console.ReadLine; IAsyncResult result = d.BeginInvoke(null, null); result.AsyncWaitHandle.WaitOne(timeoutms);//timeout e.g. 15000 for 15 secs if (result.IsCompleted) { string resultstr = d.EndInvoke(result); Console.WriteLine("Read: " + resultstr); return resultstr; } else { Console.WriteLine("Timed out!"); throw new TimedoutException("Timed Out!"); }}delegate string ReadLineDelegate();

開心每一天1111
TA貢獻1836條經(jīng)驗 獲得超13個贊
class Sample { public static void Main() { ConsoleKeyInfo cki = new ConsoleKeyInfo(); do { Console.WriteLine("\nPress a key to display; press the 'x' key to quit.");// Your code could perform some useful task in the following loop. However, // for the sake of this example we'll merely pause for a quarter second. while (Console.KeyAvailable == false) Thread.Sleep(250); // Loop until input is entered. cki = Console.ReadKey(true); Console.WriteLine("You pressed the '{0}' key.", cki.Key); } while(cki.Key != ConsoleKey.X); }}
- 3 回答
- 0 關(guān)注
- 1343 瀏覽
添加回答
舉報
0/150
提交
取消