退出应用程序后的 COM-Interop、EAccessViolation
我通过 COM-Interop 使用的 ActiveX 遇到问题。在我退出应用程序后它抛出异常,我不确定这是我的错误还是 ActiveX 的错误。
是通过 COM-Interop 初始化和释放 ActiveX 的正确方法吗?
错误消息
触发异常的示例代码
public void CreateInvoice()
{
String path = @"";
FaktNT.OLESrvClass OLESrv = null;
try
{
OLESrv = new FaktNT.OLESrvClass();
if (OLESrv.MandantLogin2() == 0)
{
try
{
//Do Stuff
}
catch (System.Exception ex)
{
//Log Error
throw;
}
finally
{
OLESrv.MandantLogout();
}
}
else
{
//Do Stuff
};
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(OLESrv);
OLESrv = null;
GC.Collect();
}
}
i am having a problem with a ActiveX i am using via COM-Interop. it`s throwing an exception after i exit my Application and i am not sure if this is my fault or the fault of the ActiveX.
is the the correct way to initilize and release an ActiveX via COM-Interop?
Error Message
Sample Code which triggers the Exception
public void CreateInvoice()
{
String path = @"";
FaktNT.OLESrvClass OLESrv = null;
try
{
OLESrv = new FaktNT.OLESrvClass();
if (OLESrv.MandantLogin2() == 0)
{
try
{
//Do Stuff
}
catch (System.Exception ex)
{
//Log Error
throw;
}
finally
{
OLESrv.MandantLogout();
}
}
else
{
//Do Stuff
};
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(OLESrv);
OLESrv = null;
GC.Collect();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不需要使用 Marshal.ReleaseComObject() 手动释放 COM 对象。这是由 .net 自动完成的(当然取决于您对本机 COM 代码中的引用计数所做的操作)。
我还会尝试检查问题是否源于本机端(例如在析构函数中,当对象被垃圾收集时调用)。
COM dll 是否生成任何本机线程,这些线程可能在对象被垃圾收集后运行?
You should not need to release the COM object manually using Marshal.ReleaseComObject(). This is done by .net automatically (depending on what you are doing to the reference counting in the native COM code of course).
I would also try to check if the problem originates on the native side (for example in a destructor, which is called when the object is garbage collected).
Is the COM dll generating any native threads, which may be running after the object was garbage collected?
这不是 .NET 消息,组件本身正在捕获访问冲突异常。从异常名称来看,它似乎是用 Delphi 编写的。在反病毒软件上制作本机代码炸弹通常不需要太多帮助。但可以肯定的是,您可能“错误”地使用了该组件。您删除了太多代码,无法真正做出明智的猜测。除此之外,在捕获它可能引发的所有异常之后在finally块中调用它是一个坏主意。
在程序退出时而不是在 GC.Collect() 调用之后让它爆炸也是不健康的。确保您尚未成功调用 ReleaseComObject 并将所有接口引用设为 null。这很常见,最好让垃圾收集器来正确处理。尽管这个消息框会轰炸终结器线程。是的,如果彻底的代码审查没有帮助,您可能需要供应商的帮助。
This is not a .NET message, the component itself is trapping the access violation exception. Looks like it was written in Delphi, judging from the exception name. Making native code bomb on an AV doesn't usually require a lot of help. But sure, you may be using the component 'incorrectly'. You stubbed out too much code to really make an informed guess. Other than that making calls on it in a finally block after you caught all exceptions that it might raise is a Bad Idea.
Getting it to bomb on program exit instead of after the GC.Collect() call is not healthy either. Sure sign that you haven't managed to call ReleaseComObject and null all the interface references. That's common, better to leave it up to the garbage collector to do it right. Albeit that this message box is going to bomb the finalizer thread. Yes, you probably need the vendor's help if a thorough code review doesn't help.
我现在解决了这个问题。事实上,我误用了 COM 对象,我错过了调用 OLESrv.EngineClose() 来彻底关闭 COM 对象。
不知何故,这一小段重要信息没有进入供应商文档......
i solved the problem now. it was in fact me misusing the COM-Object, i missed to call OLESrv.EngineClose() which closes the COM-Object cleanly.
somehow this little piece of important informationen didn`t make it into the vendors documentation ...