How do you control event triggering in C #?

I wrote a program that does some processing of an image delivered via a webcam. There is an event that fires whenever a new frame is received from the camera. However, this happens more often than we would like - so often that my image processing function does not end before a new event occurs and calls the same function again.

How can I control when an event fires? Can I do image processing, say, every 5 events? I believe I have pseudo code, but I would rather see some examples in C #.

+2
source share
4 answers

Put the callback of the event β€œprotected” as follows. Then it will not process 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: Safe thread when using fi 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(); } } } 
+2
source

You can use IObservable.SkipWhile to skip an event that reaches your handler during image processing.

This question has a similar problem:

Touch.FrameReported IObservable filtering using an arbitrary logical condition that changes over time

0
source

Then what is your pseudo code? I would like to translate it into C # .; -)

You can use the DateTime variable in which you store the last occurrence of the event, and then exit the event if less time has passed.

So, something like this if you want it to work once per second, no matter how many times it starts:

 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); } 
-1
source

Suppose you are joining an event using something similar to:

 public MyObject() { MyImageObject.Update += new UpdateEventHandler(ImageDataUpdated); } private void ImageDataUpdated(object sender, EventArgs e) { // do stuff } 

You can disconnect from the event at the beginning of the event handler, and then use the timer to reattach after a certain time interval. This will give you some precise control of the refresh rate. Sort of:

 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 are good changes that you prevent the main image object from doing additional work while the event handler is disconnected (of course, this depends on the implementation of the image object). Most likely, you save CPU cycles for your own image processing.

-2
source

All Articles