我有许多线程经常读取的数据。这些数据需要每天更新。
我的方法是使用ReaderWriterLockSlim
来管理对数据的访问。每天晚上,检测日期更改的第一个线程会将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
到目前为止,这种方法对我有用。但是我想知道是否有更好的方法来实现一个Singleton Timer,它在初始化时执行一次,然后在一段时间后执行,或者如果有人设法在不扩展Timer类的情况下更有效地执行此操作。
我需要在我当前的项目中使用其中的许多内容,所以我想确保使用一种好的方法。
感谢。
答案 0 :(得分: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并使用另一个,就像你现在一样,我只是提供它仅供参考。
答案 1 :(得分: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