Error with 'A callback was made on a garbage collected delegate'
These days we have been working with OpenCV and figured out a very strange issue.
Process terminated. A callback was made on a garbage collected delegate of type 'OpenCvSharp!OpenCvSharp.MouseCallback::Invoke'.
at OpenCvSharp.NativeMethods.highgui_waitKey(Int32, Int32 ByRef)
at OpenCvSharp.NativeMethods.highgui_waitKey(Int32, Int32 ByRef)
at Daenet.ProductIdentification.Core.ProductRecognizer+<>c__DisplayClass12_0.b__0()
Independent on OpenCV, this seems to be a very unexpected error, which has a root in the way how handlers are natively subscribed in the API, which you use (in my case OpenCV).
Here is the code, which causes the exception.
using (Mat image = new Mat()) // Frame image buffer
{
while (token.IsCancellationRequested == false)
{
capture.Read(image);
if (image.Empty())
break;
var keyPressed = Cv2.WaitKey(delay); // THIS COUSES THE EXCEPTION
}
}
When you run the application in VS (usually Debug mode) all works fine. However, after publishing of the application (no matter how => framework independent, release , single assembly, etc.), the application will fail.
The problem is internally in the registration of the key-handler inside of implementation of the method WaitKey. I guess, there is a subscription of the key-handler as anonymous method. For some reason .NET does not like this.
So, I did following. I moved the declaration of keyPressed to the class scope and declared it a s member variable. I didn't dig in MSIL to see what kind of "de-optimization" happen under the hub, but it "solves" the problem.
int keyPressed; // THIS WORKS!
using (Mat image = new Mat()) // Frame image buffer
{
while (token.IsCancellationRequested == false)
{
capture.Read(image);
if (image.Empty())
break;
keyPressed = Cv2.WaitKey(delay);
}
}
Please not, this is very unusual work-around. To understand wht exactly happen the analysis of MSIL (if even not deeper machine code) might be required.