2012-08-02 46 views
8

假設我的控制檯程序執行多個冗長的任務。在這些任務之間,我希望它暫停 - 或者幾秒鐘,直到按下任何鍵。 (以先到者爲準)等待按鍵(或)N秒到期

這些標準都是很容易檢查自己,但他們拒絕相處時,我嘗試將它們結合起來:無論是計時機制停頓了幾秒鐘ReadKey開始之前, Readkey塊直到滿意爲止。我怎樣才能滿足這兩個條件?

+3

http://stackoverflow.com/questions/57615/how-to-add-a-timeout-to-console- readline – dugas 2012-08-02 20:55:37

+0

有沒有可用的例子?這聽起來像是你只能通知主線程完成了這個操作,然後等到你可以繼續,跟蹤任何定時器並在鍵盤按下時停止它,但不能沒有例子 – 2012-08-02 21:01:41

回答

15

的一種方式做到這一點在C#4.0:

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

如果你需要知道源,然後將「Wait」調用的結果保存到一個bool變量中。如果超時,將返回false,否則返回true(意味着有可用的密鑰)。 – SPFiredrake 2012-08-02 21:41:06

+3

我應該補充說,你應該只使用這種方法來適用於沒有很多步驟的短期控制檯應用程序,因爲每當「超時」路徑被採用時,就會有一個殭屍線程等待一個鍵按。不要在10,000計數循環內嘗試這個! – lesscode 2012-08-02 21:47:59

+0

@Wayne這是一個很好的觀點,我沒有想過這個。 (我打算多次使用它)我應該採取措施防止它們堆積起來嗎? – 4444 2012-08-03 14:36:52

0

開始兩個線程。一個人聽按鍵和其他等待一段時間。讓主線等待,除非任何人完成。然後繼續並忽略其他線程響應。 :)

3

一種方式做到這一點是不定時的。創建一個使線程睡眠25毫秒的循環,然後檢查是否通過Console.KeyAvailable(非阻塞)鍵或通過DateTime.Now()到循環開始時間之間的時間超過了超時值。

+0

如果在程序運行時更改系統時間,這將無法正常工作,會嗎? – 2016-07-19 14:52:57

0

像這樣的東西?

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

從IKH的答案擴展我想倒計時與我

 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);