【问题标题】:Disposing of a c# interface wrapping an IDispatch COM interface处理包装 IDispatch COM 接口的 c# 接口
【发布时间】:2012-03-05 17:59:22
【问题描述】:

我在 C# 中实现了 IDispatch 接口。它反过来打开了一个非托管 COM 接口,该接口也公开了一个 IDispatch 接口。

    ~MyObject()
    {
       Logger.TraceDebug("About to clean up object");
       CleanupObject();
    }


    private void CleanupObject()
    {
        lock (lock_so)
        {
            try
            {
                if (so != null)
                {
                    Logger.TraceWarning("Releasing object");
                    Marshal.FinalReleaseComObject(so);
                }

            }
            catch (Exception e)
            {
            }
            so = null;
        }

    }

我遇到的问题是在正常执行期间使用对象时调用了 Finalize,这意味着稍后尝试访问包装的接口失败。当我取出清理代码时,代码工作正常,但在使用代码的程序退出时会失败(我没有来自调用应用程序的调试信息,但很可能是包装的接口尚未处理)。我不知道如何解决这个问题,并认为我的理解是不正确的。任何建议将不胜感激。

对象初始化如下:

    private void InitialiseObject()
    {
        if (so == null)
        {
            so = Activator.CreateInstance(Type.GetTypeFromProgID("MyProgID));
        }
    }

然后像这样使用:

    public void DoSomething(string String)
    {
        try
        {
            lock (lock_so)
            {
            Object[] args = new Object[1];
            args[0] = String;
            so.GetType().InvokeMember("DoSomething", BindingFlags.InvokeMethod, null, so, args);
            }
        }

所有这一切的重点是 c# 接口充当传递类,并且能够记录从第三方应用程序传递到 IDispatch 接口的信息。

【问题讨论】:

  • 你能发布这个对象是如何被使用的吗?另外,全班会很好
  • 我有点困惑。为什么在处理对象后尝试访问包装的接口?或者,问题可以改写为“为什么在完成之前调用对象的 Finalize?”
  • @Chris 我并没有尝试这样做——我的课程位于第三方应用程序和它的底层记录信息接口之间。它只是调用了它的方法。
  • 我的意思是,在不再需要对象之前不应调用 Finalize。如果在此之前调用它,则错误在于调用它的任何内容。如果您无法更改它,那么您是否可以检测它是否在处理和重新初始化时被使用?
  • @Chris 是的,我试过了。该对象将在没有设置某些参数的情况下重新初始化(它不是无状态的)。我以为这可能是某种垃圾收集发生。我知道的善良或影响力。

标签: c# com interface


【解决方案1】:

为什么需要这个?如果我知道你并且我会有一个 dispose 方法来释放一些资源,那么我将实现 IDisposable 接口。 Pattern

【讨论】:

  • 好点,我已经修改了这个问题,希望它会变得更好。总之,它是一个记录信息的传递接口。