2

我有许多线程不断读取的数据。这些数据需要每天更新。

我的方法是使用 aReaderWriterLockSlim来管理对数据的访问。每天晚上,检测日变化的第一个线程将 a 应用于WriteLock数据并更新它。

为了避免不断检查换天事件。理想情况下,我希望将 System.Timer 对象创建为单例,并让它自动启动,然后每 24 小时执行一次。

这是我的方法:

首先,我扩展了 System.Timers 以在 init 上执行回调。

using System.Timers;

namespace Utilities
{
    class AutoStartTimer : Timer
    {
        public AutoStartTimer(ElapsedEventHandler callback, int period):base(period)
        {
            callback(null, null);
            AutoReset = true;
            Elapsed += callback;
            Enabled = true;
        }
    }
}

然后我在需要它的单身人士处声明它。

private static AutoStartTimer _loadDataTimer = 
                                new AutoStartTimer(DataLoader, 86400000); // Daily

到目前为止,这种方法对我有用。但是我想知道是否有更好的方法来实现一个单例定时器,它在初始化时执行一次,然后在一段时间内执行,或者是否有人在不扩展 Timer 类的情况下设法更有效地做到这一点。

我需要在我当前的项目中使用其中的许多,所以我想确保我使用的是一种好的方法。

谢谢。

4

2 回答 2

2

使用静态类:

public static class DayManager
{
     public static readonly object SyncRoot = new object();

     private static readonly Timer dayTimer;

     static DayManager()
     {
         dayTimer = new Timer { AutoReset = true; Enabled = true; Interval = 86400000d };
         dayTimer.Elapsed += OnDayTimerElapsed;
     }

     protected void OnDayTimerElapsed(object sender, ElapsedEventArgs e)
     {
         if(DayPassedEvent != null)
         {
             DayPassedEvent(this, null);
         }
     }

     public event EventHandler DayPassedEvent;
}

现在,在每个线程中,您应该订阅 DayPassedEvent 并使用 Monitor.TryEnter(DayManager.SyncRoot) 来获取计时器管理类的锁。这意味着只有一个线程应该继续尝试更新数据,其余的应该无法获得锁并继续他们的生活。我将把它的确切实现留给你。

或者,您可以从此处的计时器管理类中删除 SyncRoot 并像您已经在做的那样使用另一个,我只是提供它仅供参考。

于 2012-11-08T12:30:55.870 回答
1

我有更好的方法给你。使用 Codeplex 的轻量级调度程序库。

一个轻量级的任务调度库,允许您轻松地在指定的时间或间隔调度回调方法的调用。支持 .NET 3.5 和 Silverlight。

该库允许您通过几行代码将灵活的调度功能包含到您的应用程序中,并提供一个流畅的 API 来配置作业:

链接: http ://scheduling.codeplex.com/

其他方法:

.NET 中的任务调度程序类:http: //msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.aspx

http://taskscheduler.codeplex.com/

http://www.codeproject.com/Articles/1763/Task-Scheduler-Library-for-NET

于 2012-11-08T12:53:19.390 回答