无法使用已与其底层 RCW 分离的 COM 对象

发布于 2024-12-05 17:06:11 字数 1919 浏览 1 评论 0原文

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

5 月这个错误是因为这个警告而出现的吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最后的乘客 2024-12-12 17:06:11

根据 MSDN 文档

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

这意味着,如果 group 与您的 OpcGroup 实例同时可以收集(这看起来很有可能),那么很可能是 group code> 已经最终确定,这很容易成为失败的原因。

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文