Async event handler - flycapture from PointGrey

448 views Asked by At

I am using Point Grey's FlyCapture API to drive some cameras. In a public class, I implemented all the starting and initializing code ; in the following _cam refers to a ManagedGigECamera. Because I have 16 cameras, I want the code to be as fast as possible, so I wanted to use tasks.

Here is the code I use:


    _cam.StartCapture(AddressOf OnImageGrabbed)

.../...

     Public Sub OnImageGrabbed(ByVal raw_image As ManagedImage)
                Dim t As Task = Task.Run(Sub() 
                                     'save image to disk or whatever
                                         End Sub)
                t.Wait()
     End Sub

The above gives -sort of- satisfaction. By viewing image timestamps, I can see that some images are saved seconds after they are grabbed, and even some images are skipped altogether... I wanted to make sure each call to OnImageGrabbed would start a new task, and tried the following, but it crashes right away with 'object not set to an instance of an object' (can't really debug, the code is running on a remote machine)



    _cam.StartCapture(AddressOf OnImageGrabbed)

.../...

     Public Async Sub OnImageGrabbed(ByVal raw_image As ManagedImage)
                Await Task.Run(Sub() 
                                     'save image to disk or whatever
                                         End Sub)
     End Sub

All in all, my questions are:

  • how can I run an event handler asynchronously ?
  • why, using the first code, do I get (what appears to be) random delays between each call to OnImageGrabbed ? I mean the differences in time between image timestamps is never the same, and tend to increase on the long run (first few images are almost synchronized, but after 1 minute or so, each image is separated by more and more time). Memory leak ? GC ?

Thanks in advance for any hint !

EDIT: In the end I changed the way the system works: I fire a software trigger on each camera using a timer, and each trigger is fired 'in parallel':

Parallel.ForEach(Of ListOfCameras)(SingleCamera, 
      Sub(aCamera, loopstate, num)
            aCamera.FireTrigger()
      End Sub)
1

There are 1 answers

1
Stephen Cleary On BEST ANSWER

Starting a task and then immediately blocking on it (via Wait) nets you nothing. You may as well just run the saving-image code directly.

The second example is actually asynchronous. You're probably getting an exception because the ManagedImage argument or one of its child objects is being disposed. Remember that the code raising the event has no idea that your code is asynchronous; it's up to you to copy out what you need from the event arguments if you're going to use it asynchronously.