控制触发的次数
本文关键字:控制 | 更新日期: 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;
}