每x分钟运行一次代码

时间:2014-12-27 04:48:52

标签: c# timer stopwatch

我正在尝试创建一个程序,每隔x分钟执行一次。我一直在尝试使用秒表功能,但它似乎没有在时间到期时运行我想要的代码。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;

namespace Testing
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch testing = new Stopwatch();
            testing.Start();

            Thread.Sleep(6001);
            TimeSpan ts = testing.Elapsed;
            int timer = Convert.ToInt32(String.Format("{0}", ts.Seconds));
            Console.Write(timer);

            while (testing.Elapsed < TimeSpan.FromMinutes(8))
            {

                timer = Convert.ToInt32(String.Format("{0}", ts.Seconds));
                if (timer % 60 == 0)
                {
                    //run x code every 1 minutes
                    Console.WriteLine("1 min" + timer);
                }


                timer = Convert.ToInt32(String.Format("{0}", ts.Seconds));
                if (timer % 120 == 0)
                {
                    //run x code every 2 minutes
                    Console.WriteLine("2 min" + timer);
                }
            }    

            testing.Stop();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

Stopwatch是一个高性能的计时器(通常具有100ns的分辨率) - 它完全不适合您尝试做的事情。 Stopwatch用于通过拍摄系统计数器的快照然后计算差异来测量时间。

由于大多数调度程序的工作都要等到需要完成作业,因此实现具有紧密循环的调度程序效率极低 - 系统正在使用CPU资源来决定在大多数情况下不执行任何操作。 / p>

要正确实现调度程序(如果这是您正在尝试执行的操作),请使用带有超时选项的ManualResetEvent

使用事件会使当前线程进入休眠状态(因此它在不执行任何操作时不使用系统资源),并且当超时到期时,事件将被触发,代码可以调用您尝试计划的函数。 / p>

如果您只想要一个简单的计时器告诉您何时间隔过去,请使用System.Timers.Timer代替:这样可以更简单地安排回调(定时器调用Elapsed事件到期)并且您不必在等待期间运行循环。

修改

如果您只想定期调用回调函数,则简单的计时器比事件更容易挂钩。以下是使用System.Timer的代码示例(不是我的代码,我从MSDN复制并粘贴了此代码,上面已链接):

private static Timer m_oTimer;

public static void Main ()
{
    m_oTimer = new System.Timers.Timer ( 2 * 1000 * 60 ); // 2 minutes
    m_oTimer.Elapsed += OnTimedEvent; // Timer callback
    m_oTimer.Enabled = true; // Start timer

    // Wait here (you can do other processing here, too)
    Console.WriteLine ( "Press the Enter key to exit the program... " );
    Console.ReadLine ();
    Console.WriteLine ( "Terminating the application..." );
}

private static void OnTimedEvent ( Object source, ElapsedEventArgs e )
{
    // This is called on a separate thread; do periodic processing here
    Console.WriteLine ( "The Elapsed event was raised at {0}", e.SignalTime );
}

答案 1 :(得分:1)

正如xxbbcc所建议的,这是一个使用带有TimeOut的ManualResetEvent.WaitOne()的实现:

    static void Main(string[] args)
    {
        int TimeOut = (int)TimeSpan.FromMinutes(2).TotalMilliseconds;
        System.Threading.ManualResetEvent mreDuration = new System.Threading.ManualResetEvent(false);
        Task.Run(() => {
            System.Threading.Thread.Sleep((int)TimeSpan.FromMinutes(30).TotalMilliseconds);
            mreDuration.Set();
        });
        while(!mreDuration.WaitOne(TimeOut))
        {
            Console.WriteLine("Two Minutes...");
        }
        Console.WriteLine("Thirty Mintues!");
        Console.ReadLine();
    }

答案 2 :(得分:0)

您应该使用Timer。如果你想让计时器停止运行,那就说,&#39; y&#39;分钟,然后您只需将开始时间存储在一个变量中并编写Timer.Stop()函数,以便在&#39; y&#39;之后执行。分钟(提示:在timer_tick事件中写入)。计时器的时间段应为所有 x y HCF 。请记住以毫秒为单位设置时间段。