无法使用已与其底层 RCW 分离的 COM 对象
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据 MSDN 文档
这意味着,如果
group
与您的OpcGroup
实例同时可以收集(这看起来很有可能),那么很可能是group
code> 已经最终确定,这很容易成为失败的原因。看起来您有 C++ 背景,在这种情况下,您应该意识到终结器在 C# 中的工作方式不同 - 您非常很少需要实现终结器。我建议您不要在终结器中执行此清理操作,而应实现 IDisposable 并在对象被处置时执行此工作。
此外,您通常不需要取消挂钩事件处理程序(除非该事件可能仍会被触发并可能在对象被释放后导致异常)。这种清理工作是为您处理的。
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.