代码之家  ›  专栏  ›  技术社区  ›  AnthonyWJones

在从流派生的类上实现dispose

  •  1
  • AnthonyWJones  · 技术社区  · 14 年前

    我正在建立一个从 Stream 包装一个组件流。不过,我遇到了一个问题,我需要释放的COM流确定。

    好吧,那很容易用 Marshal.ReleaseComObject Dispose 方法。但是我不确定它是否那么简单。这个 河流 基类已具有受保护的虚拟方法 Dispose(boolean) . 我的第一个想法是:

        ~ComStreamWrapper()
        {
            if (!_Disposed)
            {
                iop.Marshal.FreeCoTaskMem(_Int64Ptr);
                iop.Marshal.ReleaseComObject(_IStream);
            }
        }
    
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
    
            if (!_Disposed)
            {
                if (disposing)
                {
                    iop.Marshal.FreeCoTaskMem(_Int64Ptr);
                    iop.Marshal.ReleaseComObject(_IStream);
                }
                _Disposed = true;
            }
        }
    

    你会注意到没有 Dispose() 本身。我正在假设 河流 做我需要的事。那是在召唤 Diposing(true) GC.SuppressFinalize . 这个假设有错吗?

    我错过什么了吗?有更好的方法吗?你可以看到更多的基本类 answer 一个更现实的问题。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Hans Passant    14 年前

    重写disposing方法并从终结器调用它将完成该任务。请注意,在这两种情况下都需要释放资源。因此:

    ~ComStreamWrapper()
    {
        Dispose(false);
    }
    
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (!_Disposed)
        {
            iop.Marshal.FreeCoTaskMem(_Int64Ptr);
            iop.Marshal.ReleaseComObject(_IStream);
            _Disposed = true;
        }
    }
    
        2
  •  2
  •   Daniel Earwicker    14 年前

    我正在做一个假设 现有的实现 stream做了我需要的事情。那就是 呼叫拨号(真)和 抑制定型。这是 假设错误?

    这就是它的作用。好吧,它叫close,意思是:

    public virtual void Close()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }
    

    一般提示当你想要一个标准类真正做什么的明确答案时,在reflector中打开它并查看它的c反汇编。

        3
  •  0
  •   Stefan Steinegger    14 年前

    此处理方法:

      protected virtual void Dispose(bool disposing)
    

    是一种常见的模式。我假设框架中的每个dispose方法都是这样的(只要可以派生类):

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }