首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建Disposable类

如何创建Disposable类
EN

Stack Overflow用户
提问于 2014-08-20 09:45:48
回答 3查看 17.1K关注 0票数 5

我有这个类,每次我实例化这个类的时候,我需要处理它,包括类中的字段,有什么方法可以做到吗?这是我的班级

代码语言:javascript
复制
    internal class PlayerClass 
    {
        public WindowsMediaPlayer _wplayer;
    }

在使用这个类之后,我如何处理它?我试图在互联网上找到一种方法,但在测试后没有一个有效。

我试过了

代码语言:javascript
复制
internal class PlayerClass : IDisposable
{
    public WindowsMediaPlayer _wplayer;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Is this instance disposed?
    /// </summary>
    protected bool Disposed { get; private set; }

    /// <summary>
    /// Dispose worker method. See http://coding.abel.nu/2012/01/disposable
    /// </summary>
    /// <param name="disposing">Are we disposing? 
    /// Otherwise we're finalizing.</param>
    protected virtual void Dispose(bool disposing)
    {
        Disposed = true;
    }
}

我做错了吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-20 10:11:56

看起来你实现IDisposable只是为了好玩,而这对于托管代码来说并不是必需的。垃圾收集器会自动清理你身后的垃圾。

你可能需要在你的帖子中澄清为什么你要实现IDisposable

但是,我认为您的错误在于垃圾收集器不会自动调用Dispose()。如果您确实实现了IDisposable,则必须确保使用您的类的代码要么在using()语句中实例化,要么手动调用.Dispose。否则,您的dispose方法将永远不会触发。

代码语言:javascript
复制
using(var player = new PlayerClass()){
    // Do something with player
    // player.Dispose() is called automatically when you exit this using statement.
}

由于您依赖于调用者来确保调用了Dispose,因此您可能还需要查看SafeHandle (首选)或Finalize

由于当实例所拥有的资源不再需要时,类型的使用者会调用IDisposable.Dispose实现,因此您应该将托管对象包装在SafeHandle中(推荐的替代方法),或者应该重写Object.Finalize,以便在使用者忘记调用Dispose时释放非托管资源。

来源:IDisposable Interface

使用语句https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

票数 4
EN

Stack Overflow用户

发布于 2014-08-20 10:00:38

与其他答案的建议相反,实现Dispose()方法(即实现IDisposable)的it is necessary to of all created objects。这些对象是非托管资源,因此对GC是不可见的。不处理它们肯定会造成内存泄漏。(请注意,某些术语更喜欢Close()方法,而不是Dispose方法,在这种情况下,Close()方法应该是相同的。)

下面是IDisposable接口的最佳实践实现。

代码语言:javascript
复制
#region IDisposable implementation with finalizer
private bool isDisposed = false;
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) {
  if (!isDisposed) {
    if (disposing) {
      if (_wplayer != null)     _wplayer.Dispose();
   }
  }
  isDisposed = true;
}
#endregion

以下是来自上述MSDN链接的DosDonts的最佳实践:

  • DO声明一个受保护的虚空处置(布尔处置)方法来集中所有与释放非托管resources.
  • DO相关的逻辑,通过简单地调用Dispose(true),然后调用GC.SuppressFinalize(this).
  • DO NOT来实现IDisposable接口,使无参数的Dispose方法virtual.
  • DO NOT声明除Dispose()和Dispose(bool).
  • DO之外的Dispose方法的任何重载允许多次调用Dispose(bool)方法。该方法可能会选择在第一个close从Dispose(bool)中抛出异常后不执行任何操作,除非在包含进程已损坏的关键情况下(泄漏、不一致的共享状态、etc.).
  • CONSIDER提供方法Close()以及Dispose(),如果close是该区域中的标准术语)。
票数 3
EN

Stack Overflow用户

发布于 2014-08-20 09:54:18

来自MSDN documentation的。

提供了一种释放非托管资源的机制。

您不需要释放托管对象。.Net将为您提供这方面的支持。当你创建一个带有非托管资源的互操作类时,它很有用,然后你就可以释放所有的对象了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25395543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档