C#控制发射次数
我可能把这件事复杂化了,但我一直被卡住了,我发现自己为这个问题编写了非常愚蠢的解决方案 下面是一个场景。我收到了一连串的数字。1,2,3,4,5,6,6,6,5,6等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
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;
}
}
}