2008-10-17 26 views
8

Tôi cần yêu cầu đầu vào trong bảng điều khiển và đợi vài giây sau đó tôi cần phải mặc định cho một số giá trị. Làm thế nào về cơ bản có thể thời gian của chúng tôi trên giao diện điều khiển đầu vào trong C# và tiến hành với các thiết lập mặc định? Nếu bạn có mã mẫu sẽ tuyệt vời.làm cách nào để chờ trên đầu vào của bàn điều khiển trong C# trong 15 giây hoặc hơn

+0

bạn không nên gắn thẻ mọi thứ bằng "v.v". Nó khá là vô nghĩa, vì vậy tôi chỉ cần dùng nó với C#. – Mark

+0

Và "chờ đợi" thực sự không phải là rất tốt hoặc. Tôi đã thêm các thẻ thích hợp hơn. –

+1

có thể trùng lặp của [Cách thêm thời gian chờ vào Console.ReadLine()?] (Http://stackoverflow.com/questions/57615/how-to-add-a-timeout-to-console-readline) –

Trả lời

0

Một cách là lặp lại, gọi Console.In.Peek(), chờ đầu vào hoặc đủ thời gian để đi qua.

2

Xem here, nó sử dụng kỹ thuật bỏ phiếu đẹp mắt trên bảng điều khiển, mặc dù hơi thô, rất hiệu quả.

3

Bạn có thể sử dụng đối tượng bộ đếm thời gian trong System.Timers.Timer và đặt thành 60 giây, bật và nếu ai đó nhập nội dung vào bảng điều khiển chỉ cần tắt nó, nếu không thì chỉ cần xử lý những gì xảy ra trong Timer.Elapsed biến cố.

static void Main(string[] args) 
     { 
      System.Timers.Timer timer = new System.Timers.Timer(60000); 
      timer.Elapsed += new System.Timers.ElapsedEventHandler(T_Elapsed); 
      timer.Start(); 
      var i = Console.ReadLine(); 
      if (string.IsNullOrEmpty(i)) 
      { 
       timer.Stop(); 
       Console.WriteLine("{0}", i); 
      } 
     } 

     static void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      Console.WriteLine("Defult Values Used"); 
      var T = (Timer)sender; 
      T.Stop; 

     } 

Không chắc chắn đây có phải là cách tốt nhất hay không. Tôi đã thử nghiệm điều này nhưng như tôi đã nói nó có thể không phải là cách tốt nhất.

+3

Sự cố với mô hình này là ReadLine là cuộc gọi chặn không trả lại cho đến khi dòng được nhập, do đó, trong khi giá trị mặc định có thể được gửi khi bộ hẹn giờ trôi qua, chương trình sẽ không tiếp tục cho đến khi văn bản được nhập. – ICR

+0

mmm yeah đã không thực sự nghĩ về điều đó. Bugger –

2

Bạn có thể muốn cân nhắc thực hiện một việc gì đó như thêm đối số dòng lệnh để hoạt động như một chuyển đổi giữa chế độ tự động sử dụng mặc định và chế độ nhập đầy đủ của người dùng.

Nếu bạn sử dụng giải thích cụ thể yêu cầu của bạn, nó trở nên khá tầm thường. Trong mô hình này, người dùng được nhắc nhập liệu. Nếu chúng không gõ gì sau một khoảng thời gian chờ, giá trị mặc định sẽ được sử dụng. Nếu họ bắt đầu gõ một cái gì đó sau đó không có thời gian chờ được sử dụng. Điều này cũng đề cập đến việc vấn đề khả năng sử dụng từ bỏ và sử dụng một giá trị mặc định khi họ đang tham gia một thời gian dài để gõ một cái gì đó trong.

static void Main(string[] args) 
    { 
     Console.WriteLine("Please enter your name "); 
     string input; 

     if (TryReadLine(out input, 10000, true)) 
     { 
      Console.WriteLine(input); 
     } 
     else 
     { 
      Console.WriteLine("[DEFAULT]"); 
     } 

     Console.ReadKey(true); 
    } 

    const string timerString = "[{0} seconds until default value is used]"; 

    public static bool TryReadLine(out string s, double timeout, bool showTimer) 
    { 
     DateTime timeoutDateTime = DateTime.Now.AddMilliseconds(10000); 
     DateTime nextTimer = DateTime.Now; 
     while (DateTime.Now < timeoutDateTime) 
     { 
      if (Console.KeyAvailable) 
      { 
       ClearTimer(timeoutDateTime); 
       s = Console.ReadLine(); 
       return true; 
      } 

      if (showTimer && DateTime.Now > nextTimer) 
      { 
       WriteTimer(string.Format(timerString, (timeoutDateTime - DateTime.Now).Seconds)); 
       nextTimer = DateTime.Now.AddSeconds(1); 
      } 
     } 

     ClearTimer(timeoutDateTime); 
     s = null; 
     return false; 
    } 

    private static void ClearTimer(DateTime timeoutDateTime) 
    { 
     WriteTimer(new string(' ', string.Format(timerString, (timeoutDateTime - DateTime.Now).Seconds).Length)); 
    } 

    private static void WriteTimer(string s) 
    { 
     int cursorLeft = Console.CursorLeft; 
     Console.CursorLeft = 0; 
     Console.CursorTop += 1; 
     Console.Write(s); 
     Console.CursorLeft = cursorLeft; 
     Console.CursorTop -= 1; 
    } 
} 

Bởi vì tôi dành quá lâu vào nó trước khi tôi nhận ra có một cách tốt hơn , đây là một số mã tôi chỉ cần gõ lên để đọc một chuỗi từ giao diện điều khiển, với một thời gian chờ. Nó cũng có tùy chọn để có thể in thời gian hiện tại còn lại để bàn điều khiển. Nó không được kiểm tra rất kỹ lưỡng, vì vậy có khả năng có rất nhiều lỗi. Tính năng gọi lại sử dụng .NET 3.0 Action, mặc dù nếu điều này là dành cho C# 2.0, bạn chỉ có thể biến nó thành một đại biểu.

static void Main(string[] args) 
    { 
     string input; 
     Console.Write("Please enter your name ("); 
     int timerPromptStart = Console.CursorLeft; 
     Console.Write(" seconds left): "); 
     if (TryReadLine(out input, 10000, delegate(TimeSpan timeSpan) 
              { 
               int inputPos = Console.CursorLeft; 
               Console.CursorLeft = timerPromptStart; 
               Console.Write(timeSpan.Seconds.ToString("000")); 
               Console.CursorLeft = inputPos; 
              }, 
              1000)) 
     { 
      Console.WriteLine(input); 
     } 
     else 
     { 
      Console.WriteLine("DEFAULT"); 
     } 
     while (true) { } 
    } 

    /// <summary> 
    /// Tries to read a line of input from the Console. 
    /// </summary> 
    /// <param name="s">The string to put the input into.</param> 
    /// <param name="timeout">The time in milliseconds before the attempt fails.</param> 
    /// <returns>Whether the user inputted a line before the timeout.</returns> 
    public static bool TryReadLine(out string s, double timeout) 
    { 
     return TryReadLine(out s, timeout, null, 0); 
    } 

    /// <summary> 
    /// Tries to read a line of input from the Console. 
    /// </summary> 
    /// <param name="s">The string to put the input into.</param> 
    /// <param name="timeout">The time in milliseconds before the attempt fails.</param> 
    /// <param name="timerCallback">A function to call every callbackInterval.</param> 
    /// <param name="callbackInterval">The length of time between calls to timerCallback.</param> 
    /// <returns>Whether the user inputted a line before the timeout.</returns> 
    public static bool TryReadLine(out string s, double timeout, Action<TimeSpan> timerCallback, double callbackInterval) 
    { 
     const int tabLength = 6; 

     StringBuilder inputBuilder = new StringBuilder(); 
     int readStart = Console.CursorLeft; 
     int lastLength = 0; 
     bool isInserting = true; 
     DateTime endTime = DateTime.Now.AddMilliseconds(timeout); 
     DateTime nextCallback = DateTime.Now; 
     while (DateTime.Now < endTime) 
     { 
      if (timerCallback != null && DateTime.Now > nextCallback) 
      { 
       nextCallback = DateTime.Now.AddMilliseconds(callbackInterval); 
       timerCallback((endTime - DateTime.Now)); 
      } 

      if (Console.KeyAvailable) 
      { 
       ConsoleKeyInfo key = Console.ReadKey(true); 
       switch (key.Key) 
       { 
        case ConsoleKey.Enter: 
         Console.WriteLine(); 
         s = inputBuilder.ToString(); 
         return true; 

        case ConsoleKey.Backspace: 
         if (Console.CursorLeft > readStart) 
         { 
          Console.CursorLeft -= 1; 
          inputBuilder.Remove(Console.CursorLeft - readStart, 1); 
         } 
         break; 

        case ConsoleKey.Delete: 
         if (Console.CursorLeft < readStart + inputBuilder.Length) 
         { 
          inputBuilder.Remove(Console.CursorLeft - readStart, 1); 
         } 
         break; 

        case ConsoleKey.Tab: 
         // Tabs are very difficult to handle properly, so we'll simply replace it with spaces. 
         AddOrInsert(inputBuilder, new String(' ', tabLength), isInserting, readStart); 
         Console.CursorLeft += tabLength; 
         break; 

        case ConsoleKey.Escape: 
         Console.CursorLeft = readStart; 
         inputBuilder = new StringBuilder(); 
         break; 

        case ConsoleKey.Insert: 
         isInserting = !isInserting; 
         // This may be dependant on a variable somewhere. 
         if (isInserting) 
         { 
          Console.CursorSize = 25; 
         } 
         else 
         { 
          Console.CursorSize = 50; 
         } 
         break; 

        case ConsoleKey.Home: 
         Console.CursorLeft = readStart; 
         break; 

        case ConsoleKey.End: 
         Console.CursorLeft = readStart + inputBuilder.Length; 
         break; 

        case ConsoleKey.LeftArrow: 
         if (Console.CursorLeft > readStart) 
         { 
          Console.CursorLeft -= 1; 
         } 
         break; 

        case ConsoleKey.RightArrow: 
         if (Console.CursorLeft < readStart + inputBuilder.Length) 
         { 
          Console.CursorLeft += 1; 
         } 
         break; 

        case ConsoleKey.UpArrow: 
         // N.B. We can't handle Up like we normally would as we don't know the last console input. 
         //  You might want to handle this so it works appropriately within your own application. 
         break; 

        case ConsoleKey.PageUp: 
        case ConsoleKey.PageDown: 
        case ConsoleKey.PrintScreen: 
        case ConsoleKey.LeftWindows: 
        case ConsoleKey.RightWindows: 
        case ConsoleKey.Sleep: 
        case ConsoleKey.F1: 
        case ConsoleKey.F2: 
        case ConsoleKey.F3: 
        case ConsoleKey.F4: 
        case ConsoleKey.F5: 
        case ConsoleKey.F6: 
        case ConsoleKey.F7: 
        case ConsoleKey.F8: 
        case ConsoleKey.F9: 
        case ConsoleKey.F10: 
        case ConsoleKey.F11: 
        case ConsoleKey.F12: 
        case ConsoleKey.F13: 
        case ConsoleKey.F14: 
        case ConsoleKey.F15: 
        case ConsoleKey.F16: 
        case ConsoleKey.F17: 
        case ConsoleKey.F18: 
        case ConsoleKey.F19: 
        case ConsoleKey.F20: 
        case ConsoleKey.F21: 
        case ConsoleKey.F22: 
        case ConsoleKey.F23: 
        case ConsoleKey.F24: 
        case ConsoleKey.BrowserBack: 
        case ConsoleKey.BrowserForward: 
        case ConsoleKey.BrowserStop: 
        case ConsoleKey.BrowserRefresh: 
        case ConsoleKey.BrowserSearch: 
        case ConsoleKey.BrowserFavorites: 
        case ConsoleKey.BrowserHome: 
        case ConsoleKey.VolumeMute: 
        case ConsoleKey.VolumeUp: 
        case ConsoleKey.VolumeDown: 
        case ConsoleKey.MediaNext: 
        case ConsoleKey.MediaPrevious: 
        case ConsoleKey.MediaStop: 
        case ConsoleKey.MediaPlay: 
        case ConsoleKey.LaunchMail: 
        case ConsoleKey.LaunchMediaSelect: 
        case ConsoleKey.LaunchApp1: 
        case ConsoleKey.LaunchApp2: 
        case ConsoleKey.Play: 
        case ConsoleKey.Zoom: 
        case ConsoleKey.NoName: 
        case ConsoleKey.Pa1: 
         // These keys shouldn't do anything. 
         break; 

        case ConsoleKey.Clear: 
        case ConsoleKey.Pause: 
        case ConsoleKey.Select: 
        case ConsoleKey.Print: 
        case ConsoleKey.Execute: 
        case ConsoleKey.Process: 
        case ConsoleKey.Help: 
        case ConsoleKey.Applications: 
        case ConsoleKey.Packet: 
        case ConsoleKey.Attention: 
        case ConsoleKey.CrSel: 
        case ConsoleKey.ExSel: 
        case ConsoleKey.EraseEndOfFile: 
        case ConsoleKey.OemClear: 
         // I'm not sure what these do. 
         break; 

        default: 
         Console.Write(key.KeyChar); 
         AddOrInsert(inputBuilder, key.KeyChar.ToString(), isInserting, readStart); 
         break; 
       } 

       // Write what has current been typed in back out to the Console. 
       // We write out everything after the cursor to handle cases where the current input string is shorter than before 
       // (i.e. the user deleted stuff). 
       // There is probably a more efficient way to do this. 
       int oldCursorPos = Console.CursorLeft; 
       Console.CursorLeft = readStart; 
       Console.Write(inputBuilder.ToString()); 
       if (lastLength > inputBuilder.Length) 
       { 
        Console.Write(new String(' ', lastLength - inputBuilder.Length)); 
       } 
       lastLength = inputBuilder.Length; 
       Console.CursorLeft = oldCursorPos; 
      } 
     } 

     // The timeout period was reached. 
     Console.WriteLine(); 
     s = null; 
     return false; 
    } 

    // This is a rather ugly helper method to add text to the inputBuilder, either inserting or appending as appropriate. 
    private static void AddOrInsert(StringBuilder inputBuilder, string s, bool insert, int readStart) 
    { 
     if (Console.CursorLeft < readStart + inputBuilder.Length + (insert ? -1 : 1)) 
     { 
      if (!insert) 
      { 
       inputBuilder.Remove(Console.CursorLeft - 1 - readStart, 1); 
      } 
      inputBuilder.Insert(Console.CursorLeft - 1 - readStart, s); 
     } 
     else 
     { 
      inputBuilder.Append(s); 
     } 
    } 
} 
Các vấn đề liên quan