Event registration: NullReferenceException


I was testing out the connection events (disconnect/reconnect) and got a NullReferenceException with no further information.
The registration of the events works fine. The exception occurs when I unplug a camera, so I assume it’s caused when calling the ‘Disconnected’ event handler. You can find my code below.

            if (img == null || !INotify.CanNotify(img))

            long info;
            int res = INotify.NOGetStatus(img, INotify.CVNotifyEventID.DEVICE_DISCONNECTED, INotify.CVNotifyInfoCmd.IS_AVAILABLE, out info);
            if (res < 0 || info < 0)
                res = INotify.NORegister(img, INotify.CVNotifyEventID.DEVICE_DISCONNECTED, callback.OnDisconnected, IntPtr.Zero, out disconnectCookie);

            res = INotify.NOGetStatus(img, INotify.CVNotifyEventID.DEVICE_RECONNECT, INotify.CVNotifyInfoCmd.IS_AVAILABLE, out info);
            if (res < 0 || info < 0)
                res = INotify.NORegister(img, INotify.CVNotifyEventID.DEVICE_RECONNECT, callback.OnReconnected, IntPtr.Zero, out reconnectCookie);

The objects ‘img’ and ‘callback’ are not null when unplugging the camera.

Hi Tomes,

Your code for registration of the events looks good.
But the code of the callback.OnDisconnected is missing.

Please take a look in our Online GenICam User Guide: http://help.commonvisionblox.com/GenICam-User-Guide/
There you can find a C# Connection Monitoring Example.
The direct link is: http://help.commonvisionblox.com/GenICam-User-Guide/index.html?html_english_genicam_connectionmonitoring_english.htm

You can see there that you need BeginInvoke in the Callbacks to change something in the UI thread.

Otherwise it could help to give us the code and the information where you get the NullReferenceException.

Thanks for the quick answer @Sebastian.

callback.OnDisconnected is an empty method.
I’ve included the call stack of the worker thread on which the exception occurs.

ntdll.dll!NtWaitForSingleObject()  + 0x14 bytes	 
KernelBase.dll!WaitForSingleObjectEx()  + 0x9f bytes	 
clr.dll!CLREventWaitHelper2()  + 0x3b bytes	 
clr.dll!CLREventWaitHelper()  + 0x1f bytes	 
clr.dll!CLREventBase::WaitEx()  + 0x80 bytes	 
clr.dll!Thread::WaitSuspendEventsHelper()  + 0xf5 bytes	 
clr.dll!Thread::WaitSuspendEvents()  + 0x10 bytes	 
clr.dll!Thread::RareEnablePreemptiveGC()  + 0x1be3c6 bytes	 
clr.dll!Thread::RareDisablePreemptiveGC()  + 0x20fb bytes	 
clr.dll!EEDbgInterfaceImpl::DisablePreemptiveGC()  + 0x22 bytes	 
clr.dll!Debugger::SendExceptionHelperAndBlock()  + 0x1c8 bytes	 
clr.dll!Debugger::SendExceptionEventsWorker()  + 0x43a bytes	 
clr.dll!Debugger::SendException()  + 0x1f0 bytes	 
clr.dll!Debugger::LastChanceManagedException()  + 0x229 bytes	 
clr.dll!NotifyDebuggerLastChance()  + 0x82 bytes	 
clr.dll!WatsonLastChance()  + 0x563 bytes	 
clr.dll!InternalUnhandledExceptionFilter_Worker()  + 0x2a3 bytes	 
clr.dll!Debugger::UnhandledHijackWorker()  + 0x1f5 bytes	 
clr.dll!ExceptionHijackWorker()  + 0xcc bytes	 
clr.dll!ExceptionHijack()  + 0x30 bytes

The callstack does not show something from our library. This is native code.

Where do you save the delegates for the OnDisconnected and OnReconnected events?

These delegates MUST be stored as they are given to native code which is not visible for the garbage collector.
Then the garbage collector might release it which leads to a NullReferenceException.


Thanks, storing the delegates solved it. :slight_smile: