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?
According to the MSDN documentation
What this means is that if
groupis elegible for collection at the same time as yourOpcGroupinstance (which seems very likely) it may well be thatgrouphas 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
IDisposableand 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.