C#控制发射次数

C#控制发射次数,c#,events,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

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

下面是一个场景。我收到了一连串的数字。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;
 }
我想让它在命中该值时只调用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;
            }
        }
    }
}

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

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

要使其工作,首先,您需要在调用“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,您就再也不想调用它了吗?@BillGregg很抱歉澄清一下,我希望它在命中该值时调用一次,而不是在其上调用任何其他值。例如(x>4 raise event call method),如果数字流在4以下,则再次返回raise event并仅调用该方法一次。@Valmorgal:您可能希望编辑原始帖子以反映您的需求变化。@SamStanojevic感谢我更新了帖子。您可以将ifs合并到
if(Convert.ToInt32)(e.Message)>4&&!\u alertedAlready)
@StuperUser True。我个人甚至更喜欢
如果(\u alertedAlready)在锁之前返回;
。正如我所说,你可以在许多方面让它看起来更好。是的,我更喜欢事件触发一次。我该怎么做呢?:)我在回答中输入的代码会起作用,因为它只会在
x
第一次超过阈值时调用
NotifyAlert
。然后将
Notify
操作设置为不执行任何操作的函数。因此,下次
x
超过阈值时,对
Notify(x)
的调用将调用空函数。如果
x
低于阈值,则
Notify
被设置回
NotifyAlert
,导致下次
x
超过阈值时再次触发事件。我使用标志而不是单独的
Action
实例添加了示例代码到我的答案中。我将尝试使用它,是的,您是对的SendUpdate()方法中发生了一些并发性问题。我来试一试。此外,我还更新了帖子以显示大于4的答案。如果您发现这些答案很有用,欢迎接受答案:)
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;
        }
    }
}