I'm probably over complicating this but I've been stuck and I find myself coding up really silly solutions to this issue anyway.
我可能过于复杂了,但是我被卡住了,而且我发现自己在这个问题上编了一个非常愚蠢的解决方案。
Here's the scenario. I've got a stream of numbers coming in. 1,2,3,4,5,6,6,6,5,6 etc....
这是场景。我有一连串的数字。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;
}
So what's happening is the event fires for the value greater than 4, then 5, then 6...etc and in my event handler
发生的是大于4的事件,然后是5,然后是6。在我的事件处理程序中。
private static void ValueAlertHandler(object sender, DataEventArgs e)
{
lock (locker)
{
if (Convert.ToInt32(e.Message) > 4)
{
SendUpdate(e.message);
}
}
}
What I want is for it to only call the SendUpdate() once when the value is hit but it gets called for every value after that. I know I'm missing something just not sure what. Thank in advance guys.
我想要的是它只在值被命中时调用SendUpdate(),但是在它之后,它会调用每个值。我知道我错过了一些不确定的东西。提前感谢。
EDIT: To clarify. What I'd like for is the event to be raised when the number goes above 4 and call the SendUpdate() method once. Then if the numbers fall under 4 and once again go back up above 4, to call the SendUpdate() once. This process will repeat.
编辑:澄清。我想要的是,当数字超过4并调用SendUpdate()方法时,将会引发事件。然后,如果数字低于4,再回到上面4,调用SendUpdate()一次。这个过程会重复。
3 个解决方案
#1
0
To get this to work, first, you'll need to remove the condition of "if (x > 4)" around the call to "NotifyAlert(x);". You need the method to get called for all values, not just the ones greater than 4.
首先,您需要删除“如果(x > 4)”周围的调用“NotifyAlert(x)”的条件。您需要方法来调用所有值,而不仅仅是大于4的值。
So instead of...
所以……
if(x > 4)
{
NotifyAlert(x);
return;
}
... simply do ...
…简单地做……
NotifyAlert(x);
This is an important first step.
这是重要的第一步。
Then you modify your event handler code like so:
然后修改事件处理程序代码如下:
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;
}
}
}
(*) Note 1: You can also choose to move the entire logic out of the event handler, and put it around the call to NotifyAlert(x), as others have suggested. However, since you are doing some concurrency control in the event handler (locking on 'locker'), then you probably want the tracking of the values to be done serially. At least, that appears to be your intent. In that case, the logic needs to happen inside the event handler.
(*)注释1:您还可以选择将整个逻辑从事件处理程序中移出,并将其与其他用户建议的调用NotifyAlert(x)联系起来。但是,既然您在事件处理程序中执行了一些并发控制(锁定“locker”),那么您可能希望对值进行连续的跟踪。至少,这似乎是你的意图。在这种情况下,逻辑需要在事件处理程序中发生。
(*) Note 2: I notice that your post is just a bit contradictory. Your code indicates that the event starts firing when the value is greater than 4. Yet, from your written explanation, we are led to believe that the event fires when the value is equal to or greater than 4. Make sure to adjust the comparison to what your requirements really are.
注2:我注意到你的帖子有点矛盾。您的代码指示事件在值大于4时开始触发。然而,从你的书面解释,我们被引导认为事件发生时,价值等于或大于4。一定要调整与您的需求真正的比较。
#2
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;
}
}
}
}
You can rewrite this to look nicer in many ways, but the idea remains. You need an indication whether this is the first alert.
你可以用很多方法重写这个,但是这个想法仍然存在。您需要一个指示,是否这是第一个警报。
#3
0
From the sound of it you only want the event to fire when the threshold is reached rather than have the event handler have to decide whether or not to handle the event by calling SendUpdate
.
从它的声音中,您只希望在到达阈值时触发事件,而不是让事件处理程序决定是否通过调用SendUpdate来处理事件。
I'd set it up so that NotifyAlert
is only called when it actually needs to be rather than having the event handler having to know more than it might need to. For instance, does the event handler also have to know that the threshold is 4? Currently, if you need to change the threshold you have to do it in multiple places. For instance, you could do something like this:
我设置了它,这样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;
}
This is more verbose than simply using a boolean to decide whether or not to fire the event, but it also allows for flexibility - you may want to do something internally anytime the value is higher than the threshold, but not necessarily fire the event.
这比简单地使用一个布尔值来决定是否触发事件更冗长,但它也允许灵活性——您可能想在值高于阈值时在内部做一些事情,但不一定要触发事件。
With a flag: private bool alreadyAboveThreshold = false;
使用标记:私有bool alreadyAboveThreshold = false;
...
if(x > 4 && !alreadyAboveThreshold)
{
NotifyAlert(x);
alreadyAboveThreshold = true;
return;
}
else
{
alreadyAboveThreshold = false;
return;
}
#1
0
To get this to work, first, you'll need to remove the condition of "if (x > 4)" around the call to "NotifyAlert(x);". You need the method to get called for all values, not just the ones greater than 4.
首先,您需要删除“如果(x > 4)”周围的调用“NotifyAlert(x)”的条件。您需要方法来调用所有值,而不仅仅是大于4的值。
So instead of...
所以……
if(x > 4)
{
NotifyAlert(x);
return;
}
... simply do ...
…简单地做……
NotifyAlert(x);
This is an important first step.
这是重要的第一步。
Then you modify your event handler code like so:
然后修改事件处理程序代码如下:
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;
}
}
}
(*) Note 1: You can also choose to move the entire logic out of the event handler, and put it around the call to NotifyAlert(x), as others have suggested. However, since you are doing some concurrency control in the event handler (locking on 'locker'), then you probably want the tracking of the values to be done serially. At least, that appears to be your intent. In that case, the logic needs to happen inside the event handler.
(*)注释1:您还可以选择将整个逻辑从事件处理程序中移出,并将其与其他用户建议的调用NotifyAlert(x)联系起来。但是,既然您在事件处理程序中执行了一些并发控制(锁定“locker”),那么您可能希望对值进行连续的跟踪。至少,这似乎是你的意图。在这种情况下,逻辑需要在事件处理程序中发生。
(*) Note 2: I notice that your post is just a bit contradictory. Your code indicates that the event starts firing when the value is greater than 4. Yet, from your written explanation, we are led to believe that the event fires when the value is equal to or greater than 4. Make sure to adjust the comparison to what your requirements really are.
注2:我注意到你的帖子有点矛盾。您的代码指示事件在值大于4时开始触发。然而,从你的书面解释,我们被引导认为事件发生时,价值等于或大于4。一定要调整与您的需求真正的比较。
#2
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;
}
}
}
}
You can rewrite this to look nicer in many ways, but the idea remains. You need an indication whether this is the first alert.
你可以用很多方法重写这个,但是这个想法仍然存在。您需要一个指示,是否这是第一个警报。
#3
0
From the sound of it you only want the event to fire when the threshold is reached rather than have the event handler have to decide whether or not to handle the event by calling SendUpdate
.
从它的声音中,您只希望在到达阈值时触发事件,而不是让事件处理程序决定是否通过调用SendUpdate来处理事件。
I'd set it up so that NotifyAlert
is only called when it actually needs to be rather than having the event handler having to know more than it might need to. For instance, does the event handler also have to know that the threshold is 4? Currently, if you need to change the threshold you have to do it in multiple places. For instance, you could do something like this:
我设置了它,这样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;
}
This is more verbose than simply using a boolean to decide whether or not to fire the event, but it also allows for flexibility - you may want to do something internally anytime the value is higher than the threshold, but not necessarily fire the event.
这比简单地使用一个布尔值来决定是否触发事件更冗长,但它也允许灵活性——您可能想在值高于阈值时在内部做一些事情,但不一定要触发事件。
With a flag: private bool alreadyAboveThreshold = false;
使用标记:私有bool alreadyAboveThreshold = false;
...
if(x > 4 && !alreadyAboveThreshold)
{
NotifyAlert(x);
alreadyAboveThreshold = true;
return;
}
else
{
alreadyAboveThreshold = false;
return;
}