ImageStream.Wait (3rd Gen stack)

I am seeing an exception when calling ImageStream.Wait. This occurs after the application has been running for a few seconds.

The exception is
System.ArgumentException: ‘An item with the same key has already been added.’

The stack trace in the exception shows

Name Value Type
StackTrace " at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)\r\n at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)\r\n at Stemmer.Cvb.Driver.CompositeStreamBase.RegisterComposite[T](T composite)\r\n at Stemmer.Cvb.Driver.ImageStream.WaitFor(UsTimeSpan timeout, WaitStatus& waitStatus)\r\n at Irp.Acquisition.CommonVisionBlox.Model.VideoSourceCvb.WaitProcessor() in E:\Projects\Stemmer Imaging\Image Recording Platform\Plugins\Irp.Acquisition.CommonVisionBlox\Model\VideoSourceCvb.cs:line 517\r\n at Irp.Acquisition.CommonVisionBlox.Model.VideoSourceCvb.AcquisitionThread() in E:\Projects\Stemmer Imaging\Image Recording Platform\Plugins\Irp.Acquisition.CommonVisionBlox\Model\VideoSourceCvb.cs:line 473\r\n at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n at System.Threading.ThreadHelper.ThreadStart()" string

CurrentImage = _imageStream.Wait(out WaitStatus waitStatus);
if (waitStatus == WaitStatus.Ok)
ready = true;
else
Trace.WriteLine(“Frame not available”);

Am I missing something? Or maybe I am using the Wait incorrectly?

Hi and welcome @BitSmith!

Can you answer the following:

  1. Which version of :cvb: are you using exactly?
  2. Have you made sure to dispose of the acquired images (CurrentImage in your code) (and potentially node map dictionaries if you use them somewhere else in your code) once you no longer need them?

Hi,

Thanks for the quick response.

I am using 13.04.005

Currently working through the code to understand where the images are being disposed. We are not currently looking at the nodes associated with the image.

If the images were not being disposed would we not get some error telling us there were no available buffers rather than a duplicate key?

Thanks

Hi,
I did find a place where the image was not being released, which did resolve the exception.

Is this expected behaviour if the processing does not keep up with acquisition such that all available buffers are used?

Hi @BitSmith,

disposing the images is important because as long as a reference to an image buffer that has been returned by one of the Wait functions exists, this buffer will not be usable by the acquisition engine again. If the acquisition runs into a situation where all the buffers have been earmarked for an existing image reference, then the acquisition will fail with an exception (I am on your page, however, in that I would have expected a different exception to pop up; that it refers to a dictionary is a bit weird and I haven’t fully understood that yet).

I is, by the way, not recommendable to rely on the garbage collector to do its job in time - the GC is not always aware of the actual size of unmanaged memory that is associated with the managed objects, making it difficult for it to take a properly informed decision.

Generally my recommendation would be to use using:

...
using (var img = stream.Wait())
{
  // do something with img
}
...

This is just a syntactical shorthand for calling .Dispose() which makes sure that on every path that exits the braced scope img is disposed properly and the buffer becomes available again for the acquisition engine.

Hi,

Yes, I understand that.

So what would you expect to happen if the processing cant keep up and all available buffers are used? That’s effectively what is happening if the images aren’t disposed?

Personally I would not expect the Wait to throw a duplicate key exception?

How would I know if all buffers are in use?

Good Morning,

Is there a paper or documentation on Flow-Sets?

I suspect I have a basic misunderstanding of the relationship between images and flow-sets.

For instance if I want to have sufficient buffers for 10 images, do I set the the number of flow sets to 10 using RegisterManagedFlowSetPool ?

I am trying to replicate the behaviour of the ring buffer so I can acquire n frames and then stop acquisition and look back at the last n frames.

You can take a look into the application note “Migration Guide for Acquisition Stacks” located here in the Online help:
Common Vision Blox Online Reference

This is more of a complete application note of the new acquisition stack, where the Flow Sets are one part of it.