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
What this means is that if
group
is elegible for collection at the same time as yourOpcGroup
instance (which seems very likely) it may well be thatgroup
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.