2012-08-02 45 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);