开发者

How do you control event firing in C#?

I wrote a program that does some processing on an image delivered via a web cam. There is an event that fires whenever a new frame is received from the camera. However, this happens more fre开发者_高级运维quently than I'd like - so frequently that my image processing function doesn't complete before a new event appears and calls the same function again.

How can I control when the event fires? Can I execute my image processing, say, every 5 events instead? I believe I have the pseudo code figured out, but I would prefer to see some examples in C#.


Place the event callback "guarded" as follows. Then it won't be doing the processing many times at the same time.

private bool m_active;
void YourCallback(object sender, EventArgs args) 
{
  if(!m_active) 
  {
    try 
    { 
      m_active = true;
      // Do the work here... 
    }
    finally { m_active = false; }
  }
}

EDIT : Thread safe if using f.i. Semaphore.

private System.Threading.Semaphore m_Semaphore = new System.Threading.Semaphore(0, 1);
void YourCallback(object sender, EventArgs args) 
{
  if(m_Semaphore.WaitOne(0)) 
  {
    try 
    { 
      // Do the work here... 
    }
    finally { m_Semaphore.Release(); }
  }
}


You could use IObservable.SkipWhile to skip the event reaching your handler while your image processing is happening.

This question has a similar problem:

Filtering a Touch.FrameReported IObservable using arbitrary boolean condition that changes over time


Then what's the psuedo code you've got? I'd love to translate it to C#. ;-)

You could use a DateTime variable in which you store the last occurrence of the event, and then skip out of the event if less than the desired time has passed.

So, something like this if you want it to work once a second, no matter how many times it's being fired:

private DateTime _lastEvent = DateTime.Now;

public void Event()
{
    if (_lastEvent + new TimeSpan(0, 0, 1) > DateTime.Now)
        return;

    _lastEvent = DateTime.Now;

    // Now do your event
    Console.WriteLine("Tick! " + _lastEvent);
}


Supposing that you are attaching to the event using something similar to:

public MyObject()
{    
   MyImageObject.Update += new UpdateEventHandler(ImageDataUpdated); 
}

private void ImageDataUpdated(object sender, EventArgs e) 
{
    // do stuff
}

You could detach from the event in the beginning of the event handler and then use a timer to re-attach after a certain time interval. This would give you a somewhat exact control of the update rate. Something like:

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 fireing 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); 
}

Using this strategy there is a good change that you are preventing the underlying image object to do additional work while the event handler is detached (of course this depends on the implementation of the image object). Chances are that you are saving CPU-cycles for your own image processing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜