C#控制触发的次数

时间:2015-06-03 15:22:04

标签: c# events

我可能过于复杂了,但我已经陷入困境,无论如何,我发现自己编写了非常愚蠢的解决方案。

这是场景。我有一串数字进来.1,2,3,4,5,6,6,6,5,6等....

 private void NotifyAlert(int p)
    {
        EventHandler<DataEventArgs> handler = Value;
        if (handler != null)
        {
            handler(this, new DataEventArgs(p));
        }

    }



 if(x > 4)
 {
     NotifyAlert(x);  
     return;
 }

所发生的事情是事件触发的值大于4,然后是5,然后是6 ......等等,并且在我的事件处理程序中

 private static void ValueAlertHandler(object sender, DataEventArgs e)
    {
        lock (locker)
        {
            if (Convert.ToInt32(e.Message) > 4)
            {

                SendUpdate(e.message);
            }
        }
    }

我想要的是它只在命中值时调用SendUpdate()一次,但之后会调用每个值。 我知道我错过了一些不确定的东西。提前谢谢你们。

编辑:澄清。我想要的是当数字超过4并且调用SendUpdate()方法一次时要引发的事件。然后,如果数字低于4并再次回到4以上,则调用SendUpdate()一次。这个过程将重复进行。

3 个答案:

答案 0 :(得分:3)

private static bool _alertedAlready = false;

private static void ValueAlertHandler(object sender, DataEventArgs e)
{
    lock (locker)
    {
        if (Convert.ToInt32(e.Message) > 4)
        {
            if (!_alertedAlready)
            {
                SendUpdate(e.message);
                _alertedAlready = true;
            }
        }
    }
}

你可以在很多方面重写这个看起来更好,但这个想法仍然存在。您需要指出这是否是第一个警报。

答案 1 :(得分:0)

从它的声音中你只希望在达到阈值时触发事件,而不是让事件处理程序通过调用SendUpdate来决定是否处理事件。

我将其设置为只在实际需要时调用NotifyAlert,而不是让事件处理程序必须知道它可能需要的内容。例如,事件处理程序是否还必须知道阈值是4?目前,如果您需要更改阈值,则必须在多个位置执行此操作。例如,你可以这样做:

Action<int> SendNotification = (p) => NotifyAlert(p);
Action<int> IgnoreValue = (p) -> {};
Action<int> Notify = SendNotification;

...

if(x > 4)
{
    Notify(x);
    Notify = IgnoreValue;
    return;
}
else
{
    Notify = SendNotification;
    return;
}

这比简单地使用布尔值决定是否触发事件更加冗长,但它也允许灵活性 - 您可能希望在值高于阈值的任何时候在内部执行某些操作,但不一定要触发事件

带一面旗帜:     private bool alreadyAboveThreshold = false;

...

if(x > 4 && !alreadyAboveThreshold)
{
    NotifyAlert(x);
    alreadyAboveThreshold = true;
    return;
}
else
{
    alreadyAboveThreshold = false;
    return;
}

答案 2 :(得分:0)

要使其正常工作,首先,您需要在“NotifyAlert(x);”调用周围删除“if(x&gt; 4)”的条件。您需要为所有值调用方法,而不仅仅是大于4的值。

所以不是......

if(x > 4)
{
    NotifyAlert(x);  
    return;
}

......干脆......

NotifyAlert(x);

这是重要的第一步。

然后你修改你的事件处理程序代码:

private static bool isOver4 = false;    

private static void ValueAlertHandler(object sender, DataEventArgs e)
{
    lock (locker)
    {
        int x = Convert.ToInt32(e.Message);
        if (x > 4)
        {
            if (!isOver4)
            {
                SendUpdate(e.message);
                isOver4 = true;
            }
        }
        else
        {
            isOver4 = false;
        }
    }
}

(*)注1:您也可以选择将整个逻辑移出事件处理程序,并将其置于NotifyAlert(x)调用之外,正如其他人所建议的那样。但是,由于您在事件处理程序中执行了一些并发控制(锁定'locker'),因此您可能希望对值进行串行跟踪。至少,这似乎是你的意图。在这种情况下,逻辑需要在事件处理程序内部发生。

(*)注2:我注意到你的帖子有点矛盾。您的代码表示当值大于4时事件开始触发。但是,根据您的书面解释,我们会认为当值等于或大于4时事件将触发。确保根据您的要求调整比较。