【问题标题】:C# dispose is not called when object leaves scope in C++/CLI当对象在 C++/CLI 中离开作用域时,不调用 C# dispose
【发布时间】:2013-05-07 09:14:20
【问题描述】:

我有一个 C# 对象,它可用于如下所示的资源:

  public sealed class CLoadingScope
  {
    private bool isDisposed;

    public CLoadingScope()
    {}

    ~CLoadingScope()
    {
      // must be disposed otherwise it is used incorrectly
      if (!isDisposed)
      {
        throw new ApplicationException("RAII object has not been disposed");
      }
    }

    public void Dispose()
    {
      // CLEANUP CODE HERE […]
      isDisposed = true;
      GC.SuppressFinalize(this);
    }
  };

我在一些 C++/CLI 代码中使用它,如下所示:

{
  CLoadingScope scope;
  // CODE THAT USES THE RESSOURCE HERE […]
}

但这会导致抛出异常。 我期待这能起作用,因为 Dispose 是 C# 类的析构函数,堆栈对象在其作用域结束时被销毁。至少我是这样解释answer to this question 的。 由于 C#、C++ 和 C++/CLI 中终结器和析构函数的所有命名和使用混淆,我假设我混淆了一些东西。谁能告诉我什么? :)

【问题讨论】:

  • 实现 IDisposable 接口 + 使用 using(var a = new CLoadingScope()) 将调用析构函数...
  • @Sergejs 我认为在 C++/CLI 中不允许使用指令。
  • 嗯,对不起。这就是它在 C# 中的工作方式。那么,我相信你必须手动调用析构函数。
  • 要更深入地了解何时调用 dispose,请阅读此 SO 帖子 stackoverflow.com/questions/2871888/dispose-when-is-it-called,对于您可能更明确的答案,请阅读此 SO 帖子 stackoverflow.com/questions/1987251/…
  • 此外,当一个对象被释放时,它只会排队等待 GC,这将在“稍后”发生

标签: c# c++-cli destructor raii finalizer


【解决方案1】:

如果我理解正确,您已经用 C# 编写了这个类,并且正在从 C++/CLI 中使用它。

C++/CLI 会自动为您调用 Dispose 是正确的——但前提是您正在处理的类实现了 IDisposable。在您的情况下,您的类没有实现IDisposable,因此,在这种情况下,Dispose 只是一个普通方法。

如下改变你的班级:

public sealed class CLoadingScope : IDisposable

【讨论】:

  • C# 类是由另一个开发人员编写的,我只是错过了缺少接口继承。感谢您指出!
【解决方案2】:

希望这会有所帮助:

添加一个析构函数,使 c++ /cli 自动继承 IDisposable。

然后强制转换为 IDisposable 以访问 Dispose 方法

((IDisposable)obj).Dispose();

附:关于 C# Dispose() 是用 using 语句调用的,当然也可以手动调用,否则它不会自动调用,不知道为什么 C++/CLI 中的 using 等价物不调用 Dispose()

【讨论】:

  • 显式调用它在某种程度上违背了 RAII 的目的,即使其在存在异常的情况下工作。 ://
猜你喜欢
  • 2019-11-09
  • 1970-01-01
  • 2013-08-09
  • 2013-06-02
  • 2014-05-04
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
相关资源
最近更新 更多