通过附加/分离事件来控制事件触发频率。不好的做法?

时间:2011-09-29 09:06:46

标签: c# events

昨天我提出了问题How do you control event firing in C#?的答案,简而言之,问题如下:

  

“每当从相机收到一个新帧时都会触发一个事件。但是,这种情况比我想要的更频繁......我怎样才能控制事件何时触发?”

在我的回答中,我提供了下面的代码,今天早上我发现我有2个downvotes没有任何评论。我担心的主要不是代表的丢失,而是我在各种应用程序中使用自己的逻辑,并且downvotes可能表明我的实现是糟糕的实践或不利于性能。因此,我问这个问题是为了澄清以这种方式附加/分离事件控制器是否有任何问题?

public MyObject()
{    
   MyTimer = new System.Timers.Timer(100); // 10 Hz
   MyTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
   MyTimer.Enabled = true;
}

private void ImageDataUpdated(object sender, EventArgs e) 
{
   // detach from the event to keep it from firing until the timer event has fired.
   MyImageObject.Update -= new UpdateEventHandler(ImageDataUpdated);

    // do stuff
}

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // (re-)attach to the event handler.
   MyImageObject.Update += new UpdateEventHandler(ImageDataUpdated); 
}

此外,我写了以下内容,指的是在实际准备要发送给订阅者的数据之前,可以检查您是否有任何订阅者。在某些情况下,这可能会导致CPU使用率降低。对我来说似乎是对的(我自己也这样做了),但这句话有什么不对吗?

  

使用此策略很可能在分离事件处理程序时阻止底层图像对象执行其他工作(当然这取决于图像对象的实现)。您可能正在为自己的图像处理节省CPU周期。

1 个答案:

答案 0 :(得分:2)

我想他们觉得基于不相关的计时器动态添加和删除事件是一件坏事。虽然这是一个巧妙的技巧,可能有用某处某天,但我倾向于同意它们。对其他对象的事件处理程序的外部控制并不表示良好的封装。

另一种方法是在调用之间检查接收事件处理程序中是否已经过了足够的时间,并决定是否处理。这与逻辑在实时游戏或类似应用程序中的工作方式更为一致,这意味着您不会经常从外部连接和断开事件处理程序。

实际事件调用本身的开销很小,所以不要担心每帧几次调用,只要“慢速部分”(即执行实际工作的位)不是每次都执行。 / p>