Missing COM Callbacks

This was an odd one. A very simple piece of code failed on the server, but as usual works on our machines.

The c# code in question looked a bit like this:

void GetComToDoStuff()
{

    comObjectInterop.Event += MyCallBack;

    comInterop.StartDoingStuff();

    _manualResetEvent.Wait();

}

private void MyCallBack( bool finished)
{

    if(finished) _manualResetEvent.Set();

}

MyCallback gets called several times during “processing”, and is called with finished set to true once processing is complete.

The problem was (with added logging) on the server, MyCallBack was not being called for every record the com object processed. It would get called for several of them and then no more, so the last call would never arrive and release the initial call from the manual event.

FWIW the only solution (and why it worked on our machines) was the issue vanished for Debug builds.

Now our best guess for now, is that the delegate object created to handle the callback has been garbage collected early in the Release build.

So yes we have tried keeping the reference to the delegate alive by creating it in a local variable before assigning it, and doing something trivial with it after leaving the Wait, using GC.KeepAlive, turning off optimisation. No Joy. But repeatably, debug builds work without error, and release builds always fail. (Even on our machines)

Edit  And the fix is…

void GetComToDoStuff()
{
    var callbackhandler = new HandlerType(MyCallBack);
    comObjectInterop.Event += callbackhandler ;

    comInterop.StartDoingStuff();

    _manualResetEvent.Wait();

    comObjectInterop.Event -= callbackhandler ;

}

private void MyCallBack( bool finished)
{

    if(finished) _manualResetEvent.Set();

}

I guess it gives the GC a reason to keep it around, plus it’s good practice

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply