每秒执行一次操作

时间:2015-11-26 19:52:47

标签: c#

大多数在线资源都说使用Timer每隔X个间隔执行一次动作,但这看起来要简单得多。是否有任何理由为什么这会是错误的代码?

static void Main(string[] args)
{
    int prevTick = 0;
    while (true)
    {
        int curTick = DateTime.Now.Second;

        if (curTick != prevTick)
        {
            //Perform action in here
            Console.WriteLine("tick");
            prevTick = curTick;
        }
    }
}

4 个答案:

答案 0 :(得分:11)

这是"busy wait",是的,这很糟糕。您可以通过让CPU浪费周期来增强温室效应。循环将无用地每秒执行数百万次,而定时器让操作系统回调您的应用程序,因此CPU周期可用于实际执行某些有用的操作,或者只是让CPU进入低功耗状态或频率,从而节省功率。

因此,您阅读的建议使用计时器的资源是出于某种原因这样做的。所以拯救地球:使用计时器。

答案 1 :(得分:4)

在程序运行时查看任务管理器。

您将看到100 / N%CPU负载的进程,其中N是系统中CPU的总数。

你的程序基本上让一个CPU忙,从而浪费精力,并占用其他程序可以使用的资源。

答案 2 :(得分:2)

什么循环将消耗所有可用的CPU,因为没有任何东西告诉它减速。

您可以执行以下操作:

static void Main(string[] args)
    {
       int prevTick = 0;
        while (true)
        {
            int curTick = DateTime.Now.Second;

            if (curTick != prevTick)
            {
                //Perform action in here
                Console.WriteLine("tick");
                prevTick = curTick;
            }

            Thread.Sleep(100);
        }

    }

这将使它在每次循环迭代中“休息”

然而,这真的比:

更好
using System;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        private static Timer _timer;

        private static void Main(string[] args)
        {
            _timer = new Timer(state => { 
                Console.WriteLine("Doing something"); 
             }, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));

            Console.WriteLine("Press ENTER to quit the application");
            Console.ReadLine();
        }
    }
}

答案 3 :(得分:2)

是的,您正在浪费CPU周期并可能锁定程序执行。看看.NET中的Timers,例如:

public static void Main(string[] args)
{
    timer = new System.Timers.Timer(1000); // 1 seconds
    timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);

    timer.Interval = 1000;
    timer.Enabled = true;

    Console.WriteLine("Press the enter key to stop the timer");
    Console.ReadLine();
}

private static void OnTimerElapsed(object source, ElapsedEventArgs e){
  Console.WriteLine("Timer elapsed at {0}", e.SignalTime);
}