I wrote this code (simplified):
Camera cam;
cam.StreamGrabber.ImageGrabbed += (_, e) => StreamGrabber_ImageGrabbed(cam, e);
The Camera class is imported from a compulsory third-party dll that I cannot modify. For some reason the ImageGrabbed event does not specify which camera it is being grabbed from (there are multiple cameras). I need to reference the camera in the anonymous method, but now I cannot find a way to unsubscribe from the event.
When searched online they mostly boil down to:
Action myDelegate = delegate(cam, e)
{
//do something;
};
cam.StreamGrabber.ImageGrabbed += myDelegate;
cam.StreamGrabber.ImageGrabbed -= myDelegate;
but those don't work because I need to reference the cam and not the the ImageGrabbed parameters.
Please do advice me on some workarounds especially if it isn't possible.
EDIT: It seems I have oversimplified my code and missed some important details, here's a less simplified version
public class MyInterface() : IFrameGrabber
{
private var _cameras = new List<Camera>();
public void AddCamera()
{
var cam = new Camera();
cam.StreamGrabber.ImageGrabbed += (_, e) => StreamGrabber_ImageGrabbed(cam, e);
cam.OnOpened += Camera_OnOpened;
_cameras.Add(cam);
}
public void StopCamera(int id) // Just stopping not removing
{
// Unsubscribe only the ImageGrabbed event from _cameras[id] here
}
}
EDIT2: The code for the event
public void StreamGrabber_ImageGrabbed(Camera sender, ImageGrabbedEventArgs e)
{
var timer = Stopwatch.StartNew();
var serialNumber = sender.CameraInfo["SerialNumber"];
var result = e.GrabResult;
if (!result.GrabSucceeded) return;
var stride = result.ComputeStride();
if (stride == null) return;
_grabCount[serialNumber]++;
var pixelType = e.GrabResult.PixelTypeValue switch
{
PixelType.Mono8 => MatType.CV_8UC1,
_ => MatType.CV_8UC1,
}; // TODO
ImagesGrabbed?.Invoke(new(this, serialNumber, result.PixelDataPointer, result.Width, result.Height,
(int)stride, pixelType, timer.ElapsedTicks / Stopwatch.Frequency));
}
Decompiled dll code
event EventHandler<ImageGrabbedEventArgs> ImageGrabbed;
&
public class ImageGrabbedEventArgs : EventArgs
{
private IGrabResult m_grabResult;
private bool m_isClone;
public bool IsClone
{
[return: MarshalAs(UnmanagedType.U1)]
get
{
return m_isClone;
}
}
public IGrabResult GrabResult => m_grabResult;
public ImageGrabbedEventArgs(IGrabResult grabResult)
{
m_grabResult = grabResult;
m_isClone = false;
base._002Ector();
}
public ImageGrabbedEventArgs Clone()
{
ImageGrabbedEventArgs imageGrabbedEventArgs = new ImageGrabbedEventArgs(m_grabResult.Clone());
imageGrabbedEventArgs.m_isClone = true;
return imageGrabbedEventArgs;
}
public void DisposeGrabResultIfClone()
{
if (IsClone)
{
m_grabResult?.Dispose();
}
}
}
camdeclared? Is it a class field?a.b.c += ...is already a red flag. How much power do you have oncam's implementation? Can you forward internally, so you can register an eventhandler on cam, directly?Camera, I'd expect the consumer to not be able to see that it has a Streamgrabber, that has an ImageGrabbed event. That's in implementation detail. I'd expect to get images from the Camera.ImageGrabbed-event looks like and whatStreamGrabber_ImageGrabbedis?