控制触发的次数

本文关键字:控制 | 更新日期: 2023-09-27 17:53:22

我可能把这个问题复杂化了,但是我一直被困住了,我发现自己为这个问题编写了非常愚蠢的解决方案。

情况是这样的。我得到了一连串的数字。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()。此过程将重复。

控制触发的次数

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

您可以在许多方面重写它以使其看起来更好,但其思想是不变的。您需要指示这是否是第一个警报。

要使其工作,首先,您需要删除调用"NotifyAlert(x);"周围的"if (x> 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时事件会触发。

从声音来看,您只希望在达到阈值时触发事件,而不是让事件处理程序必须通过调用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;
}