C# – COM object that has been separated from its underlying RCW cannot be used

ajaxccominteropservice

I'm write XML AJAX Service with OPC server. XML AJAX Service based on this example.
And I made my service with single attribute:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

And next step I'm create class destructor:

~BoilerService()
{
    try
    {
        ReadTimer.Dispose();
        group.ReadCompleted -= new ReadCompleteEventHandler(group_ReadCompleted);
        group.Remove(true);
        server.Disconnect();
    }
    catch (Exception e)
    {
        System.IO.StreamWriter sw = new System.IO.StreamWriter("log.txt", true);
        sw.WriteLine(DateTime.Now.ToString() +e.Message+ " "+ e.Source+" "+e.StackTrace +  " destructor called.");
        sw.Close();
        sw.Dispose();
    }
}

But when I rebuild my solution in VS (files replaced in app path) I get wp3.exe unhandled exception error window (Windows 7). And in Windows event log I see folowing text:

Exception: System.Runtime.InteropServices.InvalidComObjectException

Message: COM object that has been separated from its underlying RCW cannot be used.

StackTrace:    at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, Boolean& pfNeedsRelease)
   at OPC.Data.Interface.IOPCServer.RemoveGroup(Int32 hServerGroup, Boolean bForce)
   at OPC.Data.OpcGroup.Remove(Boolean bForce)
   at OPC.Data.OpcGroup.Finalize()

What did I do wrong?


And VS 2010 give warnings:
1. 'System.Runtime.InteropServices.UCOMIEnumString' is obsolete: 'Use System.Runtime.InteropServices.ComTypes.IEnumString instead. http://go.microsoft.com/fwlink/?linkid=14202'.
2. 'System.Runtime.InteropServices.UCOMIConnectionPointContainer' is obsolete: 'Use System.Runtime.InteropServices.ComTypes.IConnectionPointContainer instead. http://go.microsoft.com/fwlink/?linkid=14202'

May be this error appear because of for this warnings?

Best Answer

According to the MSDN documentation

The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already finalized when the finalizer of Object A starts.

What this means is that if group is elegible for collection at the same time as your OpcGroup instance (which seems very likely) it may well be that group has already been finalised which could easily be the cause of your failure.

It looks like you are coming from a C++ background, in which case you should be aware that finalisers work differently in C# - its very rare that you ever need to implement a finaliser. I would recommend that instead of doing this clean up in your finaliser you instead implement IDisposable and do this work when the object is disposed.

Also you don't normally need to un-hook event handlers (unless the event may still be fired and could cause an exception after an object has ben disposed). This sort of clean up is handled for you.