C#相当于Java的timer.scheduleAtFixedRate

时间:2013-04-08 09:56:02

标签: c# timer

我需要一种方法每5分钟准确运行一次。我不能使用Timer因为我注意到它会慢慢变得不同步(即它最终会在00:01,00:06,00:11,00:16运行,等等。)

虽然它需要准确,但我不需要它太精确。每5分钟+/- 1秒就可以了,只要经过几天的运行,它仍会在5分钟的标记上准确记录。

到目前为止我所想到的是创建一个间隔为1秒的Timer,它不断检查DateTime.Now以查看是否通过了下一个5分钟标记。我想知道我错过了C#库中是否有更优雅的解决方案。

编辑:我现在有以下模板,符合我的要求。

public class ThreadTest
{
    private Thread thread;
    private long nextExecutionTime;
    private long interval;

    public void StartThread(long intervalInMillis)
    {
        interval = intervalInMillis * TimeSpan.TicksPerMillisecond;
        nextExecutionTime = DateTime.Now.Ticks;
        thread = new Thread(Run);
        thread.Start();
    }

    private void Run()
    {
        while (true)
        {
            if (DateTime.Now.Ticks >= nextExecutionTime)
            {
                nextExecutionTime += interval;
                // do stuff
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果你对Timer不满意?

然后你可以尝试让你的线程睡5分钟,而不是使用Timer

看看这个,希望有所帮助

using System;
using System.Threading;

public class Worker
{
    // This method will be called when the thread is started.
    public void DoWork()
    {
        while (!_shouldStop)
        {
            Task.Factory.Start(() => 
               {
                    // do you task async
               })
            Thread.Sleep(300000);
        }
    }

    public void DoWork2()
    {
        var watch = new Stopwatch();
        while (!_shouldStop)
        {
            watch.Start();
            Task.Factory.Start(() => 
               {
                    // do you task async
               })

            while(watch.Elapsed.ElapsedMilliseconds < 300000);
            watch.Stop();
            watch.Reset();
        }
    }

    public void RequestStop()
    {
        _shouldStop = true;
    }

    private volatile bool _shouldStop;
}

public class WorkerThreadExample
{
    static void Main()
    {
        // Create the thread object. This does not start the thread.
        Worker workerObject = new Worker();
        Thread workerThread = new Thread(workerObject.DoWork);

        // Start the worker thread.
        workerThread.Start();

        // Loop until worker thread activates.
        while (!workerThread.IsAlive);

        while (true)
        {
            //do something to make it break
        }

        // Request that the worker thread stop itself:
        workerObject.RequestStop();
        workerThread.Join();
    }
}

或者你可以试试这个: