我有许多线程不断读取的数据。该数据需要每天更新。
我的方法是使用 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
到目前为止,这种方法对我来说很有效。但是我想知道是否有更好的方法来实现单例计时器,该计时器在初始化时执行一次,然后在设定的时间内执行,或者是否有人能够在不扩展 Timer 类的情况下更有效地执行此操作。
我需要在当前的项目中使用其中的许多方法,因此我想确保我使用的是好的方法。
谢谢。
最佳答案
使用静态类:
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 并使用另一个,就像您已经在做的那样,我只是提供它仅供引用。
关于c# - System.Timer 作为单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13288695/