I need a timer equivalent which will periodically execute some specific actions (e.g. updating some progress in the database or checking for new Jobs to execute in a database).
These actions are bound to a WaitHandle which specifies if the job needs to be executed or not. So basically this could be, for example, an AutoResetEvent which is set from outside when there is a new Entity in a database and trigger the search for these new Entities. The timer is necessary because I want to limit the number of queries to the database. So if 10 new notifications arrive, the AutomaticResetEvent will only be set one time and there will be also only one query for all of these.
My first attempts looks like this:
class ConditionalScheduler
{
public void AddConditionalAction(WaitHandle handle, Action action)
{
lock (syncRoot)
{
handles.Add(handle);
actions.Add(handle, action);
}
}
private readonly object syncRoot = new object();
private readonly Dictionary<WaitHandle, Action> actions = new Dictionary<WaitHandle, Action>();
private readonly List<WaitHandle> handles = new List<WaitHandle>();
public void RunTimerLoop()
{
do
{
WaitHandle[] waitHandles = handles.ToArray();
int index = WaitHandle.WaitAny(waitHandles);
if (index >= 0)
{
WaitHandle handle = waitHandles[index];
Action action;
lock (syncRoot)
{
action = actions[handle];
}
action();
}
Thread.Sleep(5000);
} while (true);
}
The problem with this approach is that WaitHandle.WaitAny will only give me the Index of the first WaitHandle that is triggered. So if I have 2 or more WaitHandles which are triggered, then I will only execute the first actions and not the other ones.
Do you have a better design to achieve the required results of executing all actions which were triggered within the specified time period? If it simplifies the matter I could use another kind of notification mechanism instead of WaitHandles.
Thanks!