2012-08-02 31 views
8

Giả sử chương trình bảng điều khiển của tôi thực hiện nhiều tác vụ dài. Giữa các tác vụ này, tôi muốn tạm dừng - hoặc trong vài giây hoặc cho đến khi bất kỳ phím nào được nhấn. (Tùy theo điều kiện nào đến trước.)Đợi bấm phím (hoặc) N giây để hết hạn

Các tiêu chí này rất dễ kiểm tra, nhưng chúng từ chối tham gia khi thử kết hợp chúng: Cơ chế thời gian tạm dừng trong vài giây trước khi ReadKey bắt đầu, hoặc Khối Readkey ra khỏi sợi hoàn toàn cho đến khi hài lòng. Làm thế nào tôi có thể đáp ứng cả hai điều kiện?

+3

http://stackoverflow.com/questions/57615/how-to-add-a-timeout-to-console- readline – dugas

+0

Bất kỳ ví dụ nào có sẵn? Điều này nghe có vẻ như bạn chỉ có thể thông báo cho chủ đề chính rằng việc này được thực hiện, sau đó đợi ở đó cho đến khi bạn có thể tiếp tục, theo dõi bất kỳ bộ hẹn giờ nào và dừng nó nếu bàn phím được nhấn, nhưng không thể xây dựng mà không có ví dụ –

Trả lời

15

Một cách để làm điều này trong C# 4.0:

Task.Factory.StartNew(() => Console.ReadKey()).Wait(TimeSpan.FromSeconds(5.0)); 
+1

Nếu bạn cần biết nguồn, sau đó chỉ lưu kết quả của cuộc gọi 'Chờ đợi 'vào biến bool. Nếu nó đã hết thời gian, sẽ trả về false, nếu không sẽ trả về true (có nghĩa là có sẵn một khóa). – SPFiredrake

+3

Tôi nên thêm rằng bạn có lẽ chỉ nên sử dụng phương pháp này cho các ứng dụng giao diện điều khiển ngắn ngủi mà không có nhiều bước, vì mỗi khi đường dẫn "hết thời gian" được thực hiện, sẽ có một chuỗi zombie đang chờ một khóa nhấn. Đừng thử điều này bên trong một vòng lặp đếm 10.000! – lesscode

+0

@Wayne Đó là một điểm tốt, tôi đã không nghĩ về điều đó. (Và tôi có kế hoạch sử dụng nó nhiều lần) Tôi có nên thực hiện bất kỳ bước nào để ngăn không cho chúng chồng chất không? – 4444

0

Bắt đầu hai chuỗi. Một lần lắng nghe nhấn phím và chờ đợi khác một thời gian. Làm cho chủ đề chính chờ đợi trừ khi có bất kỳ chủ đề nào được thực hiện. Sau đó tiến hành và bỏ qua phản hồi luồng khác. :)

3

Một cách để làm điều này là không có một bộ đếm thời gian ở tất cả. Tạo vòng lặp làm cho luồng ngủ mất khoảng 25 mili giây và sau đó kiểm tra xem một phím đã được nhấn qua Console.KeyAvailable (không bị chặn) hay cho đến thời điểm giữa DateTime.Now() và thời gian bắt đầu vòng lặp vượt quá thời gian chờ .

+0

Điều này sẽ không hoạt động chính xác nếu thời gian hệ thống bị thay đổi trong khi chương trình đang chạy, phải không? –

0

Một cái gì đó như thế này?

bool IsPaused; 
bool IsKeyPaused; 

void Pause(){} 
void UnPause(){} 

void KeyDown(){ 
    if(!IsPaused) 
    { 
     IsPaused = true; 
     IsKeyPaused = true; 
     Pause(); 
    } 
} 
void KeyUp(){ 
    if(IsKeyPaused) 
    { 
     IsPaused = false; 
     IsKeyPaused = false; 
     UnPause(); 
    } 
} 
void TimerPause(){ 
    if(!IsPaused) 
    { 
     IsPaused = true; 
     Pause(); 
    } 
} 
void TimerEnd(){ 
    UnPause(); 
} 
2

Mở rộng từ câu trả lời của Ikh tôi muốn đếm xuống với tôi

 var original = DateTime.Now; 
     var newTime = original; 

     var waitTime = 10; 
     var remainingWaitTime = waitTime; 
     var lastWaitTime = waitTime.ToString(); 
     var keyRead = false; 
     Console.Write("Waiting for key press or expiring in " + waitTime); 
     do 
     { 
      keyRead = Console.KeyAvailable; 
      if (!keyRead) 
      { 
       newTime = DateTime.Now; 
       remainingWaitTime = waitTime - (int) (newTime - original).TotalSeconds; 
       var newWaitTime = remainingWaitTime.ToString(); 
       if (newWaitTime != lastWaitTime) 
       { 
        var backSpaces = new string('\b', lastWaitTime.Length); 
        var spaces = new string(' ', lastWaitTime.Length); 
        Console.Write(backSpaces + spaces + backSpaces); 
        lastWaitTime = newWaitTime; 
        Console.Write(lastWaitTime); 
        Thread.Sleep(25); 
       } 
      } 
     } while (remainingWaitTime > 0 && !keyRead);