【问题标题】:COM object that has been separated from its underlying RCW cannot be used无法使用已与其底层 RCW 分离的 COM 对象
【发布时间】:2011-11-21 19:47:15
【问题描述】:

我正在使用 OPC 服务器编写 XML AJAX 服务。基于this 示例的 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'

可能是因为这个警告而出现这个错误吗?

【问题讨论】:

  • 如果您想添加更多信息,请编辑您的问题,或使用您收到的答案下方的评论工具来讨论特定答案。答案字段仅用于此问题的答案,而不是讨论。

标签: c# ajax com service interop


【解决方案1】:

根据MSDN documentation

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

这意味着如果group 可以与您的OpcGroup 实例同时收集(这似乎很可能),那么很可能group 已经完成,这很可能是原因你的失败。

看起来您来自 C++ 背景,在这种情况下,您应该知道终结器在 C# 中的工作方式不同 - 您需要实现终结器的情况非常很少。我建议不要在终结器中执行此清理操作,而是实现 IDisposable 并在对象被释放时执行此工作。

此外,您通常不需要取消挂钩事件处理程序(除非事件可能仍会被触发并且可能在对象被释放后导致异常)。这种清理工作会为您处理。

【讨论】:

  • 如何为我的服务类正确实现 IDisposable?或者我必须更改 OPC 代码?如果您需要,我可以展示我的完整源代码。谢谢。
  • 而我的服务只是OPC客户端。
猜你喜欢
  • 2012-04-27
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 2022-08-09
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 2011-07-15
相关资源
最近更新 更多