I have data which is constantly being read by many threads. This data needs to be updated daily.
My approach has been to use a ReaderWriterLockSlim to manage access to the data. Every night the first thread to detect the day change applies a WriteLock to the data and updates it.
In order to avoid the constant check for the day change event. I would ideally like to create a System.Timer object as a singleton and have it automatically start and then execute every 24hrs thereafter.
This has been my approach:
First I extended System.Timers to execute the callback on 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;
}
}
}
Then I declared it at a singleton where I needed it.
private static AutoStartTimer _loadDataTimer =
new AutoStartTimer(DataLoader, 86400000); // Daily
This approach is working for me so far. However I would like to know if there are any better ways to implement a Singleton Timer which executes once on initialisation and then for a set period afterwards or if anyone has managed to do this more efficiently without extending the Timer class.
I need to use many of these in my current project so I want to make sure I am using a good approach.
Thanks.
Using a static class:
Now, in each of the threads you should subscribe to the DayPassedEvent and use Monitor.TryEnter(DayManager.SyncRoot) to acquire a lock on the timer managing class. This means that only one thread should go on to try to update the data and the rest should fail to get the lock and continue with their lives. I’ll leave the exact implementation of this up to you.
Alternatively, you could remove the SyncRoot from the timer managing class here and use another as you’re already doing, I just provided it for reference only.