如何在不锁定当前进程的情况下添加延迟(一个是Thread.Sleep())?

时间:2017-01-30 10:20:33

标签: c# timer

我对编程比较陌生,所以如果我的任何解释很难理解,我会提前道歉!

我一直在研究控制台应用程序,我试图在允许程序继续之前实现一次运行一次的控制台动画。目前,我尝试使用以下方法实现此目的:

bool check = true;

while(check == true)
{
    spin.animation();
    Thread.Sleep(500);
    check = false;
}

然而,这不起作用,因为Thread.Sleep调用会冻结线程,从而导致动画完全静止!

我试图研究解决这个问题的各种替代方法,但我目前对如何继续进行操作感到困惑。我已经看过几次提到System.Timers.Timer,但我似乎没有将它作为我库中的选项。 System.Threading.Timer是另一个经常被引用的相关问题的解决方案,但据我所知,这似乎并不完全适合我试图实现的目标。 Async / await框架是我见过的另一种选择。

我希望有人可以通过建议解决这个问题的适当方法来指出我正确的方向。如果您能提供一些关于如何在我的问题中使用它的信息,我会更加感激。

谢谢!

更新:根据要求,spin.animation()...

背后的代码
public class ConsoleAnimation
{
    private int currentAnimationFrame;

    public ConsoleAnimation()
    {
        SpinnerAnimationFrames = new[]
            {
                "........",
                "*.......",
                "**......",
                "***.....",
                "****....",
                "*****...",
                "******..",
                "*******.",
                "********",
                "*******.",
                "******..",
                "*****...",
                "****....",
                "***.....",
                "**......",
                "*.......",
            };
    }

    public string[] SpinnerAnimationFrames { get; set; }

    public void animation()
    {
        Console.CursorVisible = false;
        var originalX = Console.CursorLeft;
        var originalY = Console.CursorTop;

        Console.Write(SpinnerAnimationFrames[currentAnimationFrame]);

        currentAnimationFrame++;
        if(currentAnimationFrame == SpinnerAnimationFrames.Length)
        {
            currentAnimationFrame = 0;
        }

        Console.SetCursorPosition(originalX, originalY);
    }
}

'旋'使用' ConsoleAnimation spin = new ConsoleAnimation();'

在Program类中声明

3 个答案:

答案 0 :(得分:0)

您可以使用Timer (System.Timers.Timer)课程来切换支票:

在构造函数中初始化计时器:

    Timer _timer = new Timer(500);
    _timer.Elapsed += _timer_Elapsed;
    _timer.Start();
    while (check == true)
    {
      spin.animation();
    }

    private static void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        var timer = sender as Timer;
        check = false;
        timer.Stop();
    }

答案 1 :(得分:0)

DateTime now = DateTime.Now;
TimeSpan t = new TimeSpan(0, 0, 0, 5); // Spin for atleast 5 seconds
DateTime end = now + t;

while (DateTime.Now < end)
{
    spin.animation();
}

答案 2 :(得分:-1)

根据您的代码,我发现您正在尝试在您设置的模式中打印'*'。

但是,您在第一次循环迭代时将标志修改为 false ,这意味着您将始终将'*'视为您的控制台日志。我的代码建议是

  1. 删除Thread.Sleep(500)
  2. 而不是静态地为“check”变量赋值“false”,将值作为方法返回值获取并检查是否完成了一次迭代

    bool check = true;
    
    while(check == true)
    {
        check = spin.animation();        
    }
    

    animation()功能如下

    
    public bool animation()
        {
            Console.CursorVisible = false;
            var originalX = Console.CursorLeft;
            var originalY = Console.CursorTop;
    
    
        Console.Write(SpinnerAnimationFrames[currentAnimationFrame]);
    
        currentAnimationFrame++;
        if(currentAnimationFrame == SpinnerAnimationFrames.Length)
        {
            currentAnimationFrame = 0;
        }
    
        Console.SetCursorPosition(originalX, originalY);
    
        return currentAnimationFrame!=0?true:false;
    }