有条件的周期定时器使用等待句柄 [英] Conditional periodic timer using wait handles

查看:166
本文介绍了有条件的周期定时器使用等待句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个计时器相当于将定期执行一些具体行动(如更新数据库中的一些进展或检查新的就业机会,以在数据库中执行)。

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).

这些行为被绑定到一个WaitHandle中,指定作业是否需要被执行与否。因此,基本上,这可能是,例如,它是从外面时,有一个新的实体在数据库中,并触发寻找这些新实体设置的AutoResetEvent。因为我想限制数据库查询的数目的定时器是必要的。因此,如果10个新通知到来时,AutomaticResetEvent将只设置一次,会有也只有一个查询所有这些。

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);
    }

使用这种方法的问题是,WaitHandle.WaitAny只会给所触发的第一个WaitHandle中的我的指数。所以,如果我有2个或更多WaitHandles其被触发,那么我将只执行第一个动作,而不是其他的。

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.

你有一个更好的设计来实现执行均是在指定的时间内触发的所有行动的需要的结果?如果它简化了此事,我可以用另一种通报机制,而不是WaitHandles。

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.

谢谢!

推荐答案

也许你可以用两线程队列/散装执行去? 请注意,code下跌仅仅是一个概念,我在写没有视觉工作室,所以我做的名单上,这最好能与队列做,但我不记得的语法,而不智能感知:)。 ..

Maybe you could go with a two thread queue / bulk execution? Note that the code down is just a concept I'm writing without visual studio so I'm doing on a list, this had better to be done with a Queue but I don't remember the syntax without intellisense :) ...

private readonly Dictionary<WaitHandle, Action> actions = new Dictionary<WaitHandle, Action>();
    private readonly List<WaitHandle> handles = new List<WaitHandle>();
    private readonly List<WaitHandle> triggeredHandles = new List<WaitHandle>();

// thread 1
    public void CheckLoop()
    {
        do
        {
            WaitHandle[] waitHandles = handles.ToArray();
            int index = WaitHandle.WaitAny(waitHandles);

            if (index >= 0)
            {
                lock (triggeredHandles)
                {
                   triggeredHandles.Add(waitHandles[index]);
                }

            }            
        } while (true);
    }

// thread 2
public void RunLoop()
    {
        do
        {
            lock(triggeredHandles)
            {
                foreach (var th in triggeredHandles) {

                   Action action;
                   lock (syncRoot)
                   {
                       action = actions[th];
                   }

                   action();                   
                }
                triggeredHandles.Clear();
            }
            Thread.Sleep(5000);
        } while (true);
    }

这篇关于有条件的周期定时器使用等待句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆