不能使用已与其底层RCW分离的COM对象

本文关键字:分离 RCW COM 对象 不能 | 更新日期: 2023-09-27 18:09:08

我写XML AJAX服务与OPC服务器。基于此示例的XML AJAX服务。我的服务只有一个属性:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

下一步我要创建类析构函数

~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();
    }
}

但是当我在VS中重建我的解决方案(在应用程序路径中替换的文件)时,我得到wp3.exe未处理的异常错误窗口(Windows 7)。在Windows事件日志中,我看到以下文本:

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()

我做错了什么?


和VS 2010给出警告:1. "System.Runtime.InteropServices。UCOMIEnumString'已过时:'使用System.Runtime.InteropServices.ComTypes.IEnumString代替。http://go.microsoft.com/fwlink/?linkid=14202"。2. "System.Runtime.InteropServices。UCOMIConnectionPointContainer'已过时:'使用System.Runtime.InteropServices.ComTypes.IConnectionPointContainer代替。http://go.microsoft.com/fwlink/?linkid=14202 '

这个错误会因为这个警告而出现吗?

不能使用已与其底层RCW分离的COM对象

根据MSDN文档

两个对象的终结器不能保证以任何特定的顺序运行,即使一个对象引用了另一个对象。也就是说,如果对象A有对对象B的引用,并且两者都有终结器,那么当对象A的终结器启动时,对象B可能已经结束了。

这意味着如果group与您的OpcGroup实例同时符合收集条件(这似乎很有可能),则很可能group已经完成,这很容易成为您失败的原因。

看起来你来自c++背景,在这种情况下,你应该意识到终结器在c#中的工作方式不同-它的非常很少需要实现终结器。我建议不要在你的终结器中做这个清理,而是实现IDisposable,并在对象被处置时做这个工作。

通常也不需要取消钩子事件处理程序(除非事件可能仍然被触发,并且在对象被处置后可能导致异常)。