.NET,每分钟(在分钟)事件。 是计时器的最佳选择?(.NET, event every mi

2019-06-21 01:09发布

我想要做的东西在使用C#Windows窗体应用程序中的分钟(由时钟)的每一分钟。 我只是想知道最新最好的路要走呢?

我可以用一个定时器,其时间间隔设置为60000,但要获得它在分钟运行,我不得不启用它的精确分钟,没有真正可行的。

我可以用一个定时器,其时间间隔设置为1000。那么它的Tick事件中,我可以检查时钟对我设置,如果分已经改变,那么我的代码运行可变电流分钟。 这让我担心,因为我让我的电脑做一次检查,以便开展工作,每1分钟,每1秒。 当然这是丑陋的?

我使用Windows窗体和.NET 2.0所以不希望使用自带的.Net 3.5 DispatchTimer

这必须是一个相当普遍的问题。 你们中有更好的方式来做到这一点?

Answer 1:

建立在回答从中可以漂移和不完全勾选上只内分一秒分钟阿奎那:

static System.Timers.Timer t;

static void Main(string[] args)
{
    t = new System.Timers.Timer();
    t.AutoReset = false;
    t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
    t.Interval = GetInterval();
    t.Start();
    Console.ReadLine();
}

static double GetInterval()
{
    DateTime now = DateTime.Now;
    return ((60 - now.Second) * 1000 - now.Millisecond);
}

static void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Console.WriteLine(DateTime.Now.ToString("o"));
    t.Interval = GetInterval();
    t.Start();
}

在我的盒子这段代码蜱一贯内每分钟的.02s:

2010-01-15T16:42:00.0040001-05:00
2010-01-15T16:43:00.0014318-05:00
2010-01-15T16:44:00.0128643-05:00
2010-01-15T16:45:00.0132961-05:00


Answer 2:

怎么样:

int startin = 60 - DateTime.Now.Second;
var t = new System.Threading.Timer(o => Console.WriteLine("Hello"), 
     null, startin * 1000, 60000);


Answer 3:

创建一个Timer一个触发间隔为1秒(通常不只是一个简单的检查)控制会忽略的开销添加到您的应用程序。

简单地比较价值Environment.TickCountDateTime.Now到最后存储的时间(之前的“剔分钟”),你应该有一个合理的精确的解决方案。 这两个时间值的分辨率大约是15毫秒,这应该足以满足您的目的。

注意,使用这样的间隔Timer控制不能保证是准确的,甚至现在的任何地方,因为它运行在Windows的消息循环,这是与用户界面的响应绑英寸 千万不要依靠它甚至适度精确的时间-尽管这是烧制重复事件,你可以用更灵敏的方法来检查的时候,如上面给出的两个之一不够好。



Answer 4:

你可以用它会照顾大量的定时器有关的问题,为您的反应扩展(时钟的变化,应用休眠等)钉这一点。 使用NuGet包RX-主,这样的代码:

Action work = () => Console.WriteLine(DateTime.Now.ToLongTimeString());

Scheduler.Default.Schedule(
    // start in so many seconds
    TimeSpan.FromSeconds(60 - DateTime.Now.Second), 
    // then run every minute
    () => Scheduler.Default.SchedulePeriodic(TimeSpan.FromMinutes(1), work));               

Console.WriteLine("Press return.");
Console.ReadLine();

读到这里(搜索“介绍ISchedulerPeriodic”)看到这个正在照顾的所有问题: http://blogs.msdn.com/b/rxteam/archive/2012/06/20/reactive-extensions-v2-0 -release候补可供now.aspx



Answer 5:

我仅仅指刚写了使用WPF DispatcherTimer这个类,但你可以交换调度员当它从睡眠状态唤醒,它支持改变任何计时器。

类构造具有固定时间步长和supprts启动/停止/复位,启动/停止/开始像一个恢复操作。 定时器就像是这方面的一个秒表。

时钟的实现将简单地用1秒的间隔创建类,并听取事件。 警惕,虽然这是一个实时时钟,如果剔事件发生比间隔更长的时间来完成,你会发现,时钟会尝试赶上实时这将导致蜱事件的突发被提出。

public class FixedStepDispatcherTimer
{
    /// <summary>
    /// Occurs when the timer interval has elapsed.
    /// </summary>
    public event EventHandler Tick;

    DispatcherTimer timer;

    public bool IsRunning { get { return timer.IsEnabled; } }

    long step, nextTick, n;

    public TimeSpan Elapsed { get { return new TimeSpan(n * step); } }

    public FixedStepDispatcherTimer(TimeSpan interval)
    {
        if (interval < TimeSpan.Zero)
        {
            throw new ArgumentOutOfRangeException("interval");
        }
        this.timer = new DispatcherTimer();
        this.timer.Tick += new EventHandler(OnTimerTick);
        this.step = interval.Ticks;
    }

    TimeSpan GetTimerInterval()
    {
        var interval = nextTick - DateTime.Now.Ticks;
        if (interval > 0)
        {
            return new TimeSpan(interval);
        }
        return TimeSpan.Zero; // yield
    }

    void OnTimerTick(object sender, EventArgs e)
    {
        if (DateTime.Now.Ticks >= nextTick)
        {
            n++;
            if (Tick != null)
            {
                Tick(this, EventArgs.Empty);
            }
            nextTick += step;
        }
        var interval = GetTimerInterval();
        Trace.WriteLine(interval);
        timer.Interval = interval;
    }

    public void Reset()
    {
        n = 0;
        nextTick = 0;
    }

    public void Start()
    {
        var now = DateTime.Now.Ticks;
        nextTick = now + (step - (nextTick % step));
        timer.Interval = GetTimerInterval();
        timer.Start();
    }

    public void Stop()
    {
        timer.Stop();
        nextTick = DateTime.Now.Ticks % step;
    }
}


Answer 6:

创建方法或把这段代码在您想要的计时器开始:

 int time = 60 - DateTime.Now.Second; // Gets seconds to next minute
        refreshTimer.Interval = time * 1000;
        refreshTimer.Start();

然后在你的Tick事件的时间间隔设置为60000:

  private void refreshTimer_Tick(object sender, EventArgs e)
    {
        refreshTimer.Interval = 60000; // Sets interval to 60 seconds
        // Insert Refresh logic
    }


Answer 7:

运行一些代码,看看是否已分每秒更换一次不应该要求太多的CPU时间,应该可以接受。



Answer 8:

什么Quartz.NET ? 我认为这是一个很好的框架做同步操作。



Answer 9:

通过利用ReactiveExtensions的,如果你有兴趣做的是打印到控制台简单的东西,你可以使用下面的代码。

using System;
using System.Reactive.Linq;
namespace ConsoleApplicationExample
{
    class Program
    {
        static void Main()
        {
            Observable.Interval(TimeSpan.FromMinutes(1))
            .Subscribe(_ =>
            {                   
                Console.WriteLine(DateTime.Now.ToString());
            });
            Console.WriteLine(DateTime.Now.ToString()); 
            Console.ReadLine();
        }
    }
}


Answer 10:

您可以设置两个定时器。 最初的短间隔定时器(也许是为了激发每一秒,但presice第二定时器必须如何开枪分钟依赖性)。

你会只火,直到达到主间隔定时器的期望开始时间短的间隔定时器。 一旦达到初始时间,第二主间隔定时器可以被激活,而短间隔定时器可被停用。

void StartTimer()
{

  shortIntervalTimer.Interval = 1000;
  mainIntervalTimer.Interval = 60000; 

  shortIntervalTimer.Tick += 
    new System.EventHandler(this.shortIntervalTimer_Tick);
  mainIntervalTimer.Tick += 
    new System.EventHandler(mainIntervalTimer_Tick);

  shortIntervalTimer.Start();

}

private void shortIntervalTimer_Tick(object sender, System.EventArgs e)
{
  if (DateTime.Now.Second == 0)
    {
      mainIntervalTimer.Start();
      shortIntervalTimer.Stop();
    }
}

private void mainIntervalTimer_Tick(object sender, System.EventArgs e)
{
  // do what you need here //
}


Answer 11:

或者,你可以睡暂停执行直到超时应该是接近你想要的时间。 当睡眠结束,因此可以节省你的CPU时间,让CPU断电处理事件之间这只会唤醒计算机。

这有修改超时值,这样就不会漂移的优势。

int timeout = 0;

while (true)  {
  timeout = (60 - DateTime.Now.Seconds) * 1000 - DateTime.Now.Millisecond;
  Thread.Sleep(timeout);

  // do your stuff here
}


Answer 12:

使用一个定时器设置为运行每一秒(或毫秒,无论你的准确度阈值),然后代码运行,当且仅当当前时间是门槛过去的“上分”点中的功能的方法。



Answer 13:

什么我使用计划的任务是System.Threading.Timer(System.Threading.TimerCallback,对象,INT,INT)设置为我想在此基础上以毫秒为单位提供的间隔来执行代码回调周期值。



Answer 14:

关于阿奎那的组合的答案,‘投票’是什么:(道歉语言的混合物)

def waitForNearlyAMinute:
    secsNow = DateTime.Now.Second;
    waitFor = 55 - secsNow;
    setupTimer(waitFor, pollForMinuteEdge)

def pollForMinuteEdge:
    if (DateTime.Now.Second == 0):
        print "Hello, World!";
        waitForNearlyAMinute();
    else:
        setupTimer(0.5, pollForMinuteEdge)


文章来源: .NET, event every minute (on the minute). Is a timer the best option?