Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Event not raised and Threads

I'm having some trouble with an event. The problem is that sometimes the event just isn't raised.

We've got a camera from an company which we've implemented in our software. In the software we register an event which is triggered every time an image is taken on the camera.

I've noticed that with an increase of need in processing power (e.g. calculating average mean on images and working with bigger images) will sometimes result in the event not being raised. Furthermore I can make this happen even more often by increasing the frame-rate of the camera. I know a frame is missing because they are marked with ID's.

In their own demo software I'm able to run at the same speed with no problems. Their software doesn't perform any calculations or anything, it just receives and displays the image.

I'm baffled because this is the closest connection to the camera I have; all I can do is wait for the event to rise. I'd like to ask you if you know of any situation where an event would be ignored.

To me it looks like the camera is firing an image but for some reason the even't isn't picking up (overload?).

Here is some of the related code:

private void Camera_OnFrameReceived(AVT.VmbAPINET.Frame frame)
{
    if (frame.ReceiveStatus == VmbFrameStatusType.VmbFrameStatusComplete)
    {
        if (lastID != 0 && lastID != 1)
        {
            if(frame.FrameID - lastID > 1)
                Debug.WriteLine("HEEEEYYY SKIPPED A FRAME, ID: " + frame.FrameID.ToString() + " TOTAL LOST: " + (frame.FrameID - lastID - 1).ToString());
        }
        lastID = frame.FrameID;
        //Debug.WriteLine("Frame received from camera");

        //if the camera is in single mode, dont raise the event (frame already taken)
        if (Mode == CaptureMode.Single)
            return;

        //set the last frame
        _frameQueue.Enqueue(frame);

        if (FilmFrameReady != null)
        {
            DateTime dateTime = Accurate.DtNow;
            frameTaken = false;
            FilmFrameReady(this, new FilmFrameReadyArgs(this, dateTime));
        }
    }
}

As you can see I take the frame, add it to a queue, and then tell my outside classes that there's something for them to fetch. I'm releasing the event thread as quickly as possible.

Summary:

My event is sometimes not raised. I think it's because the main thread is working too hard.

Do you have any experience with events sometimes not being raised?

like image 311
JohanLejdung Avatar asked Oct 23 '13 14:10

JohanLejdung


1 Answers

Odds are the event handlers all need to complete before the code that fires the event is able to fire more events; it probably only has a single thread to fire the events. When it has a new event to fire before the current event is finished it could either skip firing that event (which is what it appears to do) or queue it up for later. If it does the latter it runs the risk of getting really far behind if the event handlers almost always take longer than the time between event firings. Getting behind means both an ever growing amount of memory consumed, as well as that events are being fired for something that happened quite some time ago, which (in some contexts) can be a problem.

You could resolve this yourself by having an event handler that doesn't actually do the work, but rather puts the information into a queue (a BlockingCollection would be good here) so that another thread (or threads, if your processing can safely be done in parallel) can process the items. Be careful though, unless you only occasionally take "too long" to process the events you can end up with a queue that just grows and grows, or just floods your machine with more threads than it can handle. If you only occasionally take "too long" then this will help even it out without creating a backlog.

In the end, if your processing just takes too long you may have no choice but to focus on improving the performance of your event handler such that it takes less time (on average) than the frame rate, or else just limit the frame rate to what your processing can handle.

like image 118
Servy Avatar answered Sep 19 '22 04:09

Servy