退出应用程序后,COM-Interop,EAccessViolation

时间:2011-05-26 08:40:36

标签: c# exception com-interop

我遇到的问题是我通过COM-Interop使用的ActiveX。退出我的应用程序后它会抛出一个异常,我不确定这是我的错还是ActiveX的错误。

是通过COM-Interop初始化和释放ActiveX的正确方法吗?

错误消息

the error msg

触发异常的示例代码

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

3 个答案:

答案 0 :(得分:1)

您不需要使用Marshal.ReleaseComObject()手动释放COM对象。这是由.net自动完成的(取决于您对本机COM代码中的引用计数所做的操作)。

我还会尝试检查问题是否源自本机端(例如,在析构函数中,当对象被垃圾回收时调用)。

COM dll是否会生成任何本机线程,这些线程可能在对象被垃圾回收后运行?

答案 1 :(得分:1)

这不是.NET消息,组件本身正在捕获访问冲突异常。看起来它是用Delphi编写的,从异常名称来判断。在AV上制作本机代码炸弹通常不需要很多帮助。但可以肯定的是,您可能正在使用“错误”组件。你掏出太多的代码来真正做出明智的猜测。除了在你抓住所有异常之后在finally块中调用它之外,这可能是一个坏主意。

让它在程序退出时炸弹,而不是在GC.Collect()调用之后也不健康。确实没有设法调用ReleaseComObject并取消所有接口引用。这是常见的,最好将它留给垃圾收集器来做正确的事。虽然这个消息框将炸弹终结器线程。是的,如果彻底的代码审查没有帮助,您可能需要供应商的帮助。

答案 2 :(得分:1)

我现在解决了这个问题。实际上我误用了COM-Object,我错过了调用OLESrv.EngineClose()来干净地关闭COM-Object。

不知何故,这一小部分重要信息并没有进入供应商的文档......