【问题标题】:C# | Console app | How to make the program wait (time in ms) before executing the next line?C# |控制台应用程序 |如何在执行下一行之前让程序等待(以毫秒为单位的时间)?
【发布时间】:2019-09-03 13:10:09
【问题描述】:

我正在构建一个 c# 控制台应用程序(.NET 框架),我想通过使用一些“动画”来制作一个漂亮的应用程序。 我想打印“Press any Key to continue ...”并让它闪烁(出现然后消失,直到用户实际按下任何键。

 do
    {
       while (!Console.KeyAvailable)
         {
             Console.WriteLine("Press any key to continue...");

     /* here i want the program to wait for like 500ms,
      clear console and wait 500ms again before rewriting line*/

             Console.Clear();
         }
     } while (Console.ReadKey(true).Key != ConsoleKey.Escape);

【问题讨论】:

  • Thread.Sleep(500) ?

标签: c# timer console-application delay sleep


【解决方案1】:

一个简单的方法是使用

System.Threading.Thread.Sleep(5000); //暂停5秒。所以要闪存做这个。

Console.Clear();
Console.WriteLine("SomeText");
System.Threading.Thread.Sleep(1000);
Console.Clear();
Console.WriteLine("SomeText");
System.Threading.Thread.Sleep(1000);
/// ETC.. 

Console.WriteLine("Press Any key To Continue...)

这是一种简单的方法,有助于您理解编码。如果你想让它继续闪烁,那么只需将它放在一个循环内。然而!请记住,这有效地“暂停”了代码运行。因此,如果它在暂停线上,它将不允许用户按下键继续。这就是为什么我把最后的Console.WriteLine(); 放在底部。如果您希望用户能够随时按下某个键并使其不断闪烁,那么您将不得不参与多线程,这可能比您感兴趣的要复杂一些。

【讨论】:

    【解决方案2】:

    首先,我会为此使用Thread.Sleep。休眠你的主线程提供了相当粗糙的用户体验......这是一种快速而肮脏的方法,但不是该方法的真正用途。

    这是一个使用计时器闪烁一行文本的快速示例。

    using System.Timers;
    class Program
    {
        static void Main(string[] aszArgs)
        {
            Timer myTimer = new Timer(500);
            myTimer.Elapsed += MyTimer_Elapsed;
            myTimer.Enabled = true;
    
            //Wait for a key. Or do other work... whatever you want
            Console.ReadKey();
        }
    
        private static bool cleared = true;
        private static void MyTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (cleared)
                Console.WriteLine("Flash text");
            else
                Console.Clear();
    
            cleared = !cleared;
        }
    }  
    

    我在这个例子中使用了System.Timers.Timer,它有一些可靠的文档和例子here

    【讨论】:

      【解决方案3】:

      您可以像这样以相等的间隔执行一批操作:

      using System;
      using System.Threading;
      
      namespace ConsoleApp
      {
          class Program
          {
              static void Main(string[] args)
              {
                  new Program().Run();
              }
      
              private void Run()
              {
                  do
                  {
                      while (!Console.KeyAvailable)
                          this.InvokeWithIntervals(1000,
                                                   () => Console.WriteLine("Press any key to continue..."),
                                                   () => Console.Clear());
                  } while (Console.ReadKey(true).Key != ConsoleKey.Escape);
              }
      
              private void InvokeWithIntervals(int interval, params Action[] actions)
              {
                  foreach(var action in actions)
                  {
                      action.Invoke();
                      Thread.Sleep(interval);
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        一种稍微不同的方法是使用Stopwatch 类来测量时间,并且只有在我们通过了指定的“闪烁间隔”时才更改文本。

        我们可以编写一个方法来执行此操作,它需要一个 string prompt 来显示,一个 TimeSpan interval 指定在闪烁文本之间等待多长时间。

        在代码中,我们将捕获光标位置和控制台颜色,启动秒表,然后每次秒表经过interval 指定的时间量时,我们将交换Console.ForegroundColorConsole.BackgroundColor

        该方法将执行此操作,直到用户按下一个键,我们将返回给调用者:

        private static ConsoleKey FlashPrompt(string prompt, TimeSpan interval)
        {
            // Capture the cursor position and console colors
            var cursorTop = Console.CursorTop;
            var colorOne = Console.ForegroundColor;
            var colorTwo = Console.BackgroundColor;
        
            // Use a stopwatch to measure time interval
            var stopwach = Stopwatch.StartNew();
            var lastValue = TimeSpan.Zero;
        
            // Write the initial prompt
            Console.Write(prompt);
        
            while (!Console.KeyAvailable)
            {
                var currentValue = stopwach.Elapsed;
        
                // Only update text with new color if it's time to change the color
                if (currentValue - lastValue < interval) continue;
        
                // Capture the current value, swap the colors, and re-write our prompt
                lastValue = currentValue;
                Console.ForegroundColor = Console.ForegroundColor == colorOne 
                    ? colorTwo : colorOne;
                Console.BackgroundColor = Console.BackgroundColor == colorOne 
                    ? colorTwo : colorOne;
                Console.SetCursorPosition(0, cursorTop);
                Console.Write(prompt);
            }
        
            // Reset colors to where they were when this method was called
            Console.ForegroundColor = colorOne;
            Console.BackgroundColor = colorTwo;
        
            return Console.ReadKey(true).Key;
        }
        

        现在,在调用方,我们将向其传递文本“按转义键继续”和我们想要等待的时间量(在您的情况下为TimeSpan.FromMilliseconds(500)),然后我们可以无限地调用它@ 987654329@循环,直到用户按下ConsoleKey.Escape

        private static void Main()
        {
            // Flash prompt until user presses escape
            while (FlashPrompt("Press escape to continue...", 
                TimeSpan.FromMilliseconds(500)) != ConsoleKey.Escape) ;
        
            // Code execution continues after they press escape...
        }
        

        这里的好处是您可以重复使用逻辑并可以指定更短或更长的闪存时间。您还可以通过在调用方法之前指定它们来更改“闪烁”的颜色(或者可以编写方法以将它们作为参数)。

        例如,试试这个:

        private static void Main()
        {
            Console.WriteLine("Hello! The text below will flash red " + 
                "and green once per second until you press [Enter]");
        
            Console.ForegroundColor = ConsoleColor.Red;
            Console.BackgroundColor = ConsoleColor.Green;
        
            while (FlashPrompt("Press [Enter] to continue...", 
                TimeSpan.FromSeconds(1)) != ConsoleKey.Enter) ;
        
            Console.ResetColor();
        
            // Code will now continue in the original colors
        }
        

        【讨论】:

        • 你忘了提到我需要添加Using System.Diagnostics; 我试图找到一个秒表类并手动添加它,但后来我想通了!谢谢。这很有帮助。
        【解决方案5】:

        我对@9​​87654321@ 进行了改进,这会导致 CPU 使用率过高。我的回答让 CPU 在等待期间处于空闲状态,但需要添加对 System.Windows.Forms 的引用。

        private static void Timer_Tick (object sender, EventArgs e)
        {
            ((System.Windows.Forms.Timer)sender).Stop();
        }
        private static ConsoleKey FlashPrompt(string prompt, TimeSpan interval)
        {
            // Capture the cursor position and console colors
            var cursorTop = Console.CursorTop;
            var colorOne = Console.ForegroundColor;
            var colorTwo = Console.BackgroundColor;
            
            // Write the initial prompt
            Console.Write(prompt);
        
            // Set up timer
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Tick += Timer_Tick;
            timer.Interval = (int)interval.TotalMilliseconds;
            while (!Console.KeyAvailable)
            {
                // Wait the required interval, checking every 100ms
                timer.Start();
                while (!Console.KeyAvailable && timer.Enabled)
                {
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(100);
                }
        
                // Wwap the colors, and re-write our prompt
                Console.ForegroundColor = Console.ForegroundColor == colorOne 
                    ? colorTwo : colorOne;
                Console.BackgroundColor = Console.BackgroundColor == colorOne 
                    ? colorTwo : colorOne;
                Console.SetCursorPosition(0, cursorTop);
                Console.Write(prompt);
            }
        
            // Reset colors to where they were when this method was called
            Console.ForegroundColor = colorOne;
            Console.BackgroundColor = colorTwo;
        
            return Console.ReadKey(true).Key;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-17
          • 1970-01-01
          • 2022-08-19
          • 2018-11-18
          • 1970-01-01
          • 1970-01-01
          • 2012-12-23
          • 2011-04-23
          相关资源
          最近更新 更多