【问题标题】:Do i need to call garbage collector inside my Dispose() method我需要在我的 Dispose() 方法中调用垃圾收集器吗
【发布时间】:2016-03-30 01:44:03
【问题描述】:

我对在我的 asp.net mvc-5 Web 应用程序中实现 Dispose 的 write syntx 有疑问。

现在我使用 Visual Studio 2013 创建了一个新的 asp.net mvc-5 Web 应用程序,并将我的数据库表映射到一个 edmx 文件中。然后我创建了一个新的控制器类。现在Dispose() 的默认代码如下在控制器类的末尾:-

public class DeptsController : Controller
    {
  private ApplicationDbContext db = new ApplicationDbContext();

  //code goes here..

  protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

但同时我发现许多在线文章和书籍使用以下语法来处理当前请求,如link:-

protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

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

所以我有这个问题:- 我应该/更喜欢使用哪种 dispose 语法?这两种方法会产生相同的结果吗?

【问题讨论】:

  • 我的代码在您声称有显着差异的两个示例之间看起来几乎相同...请说明您认为不同的部分(假设您了解 override 的含义)
  • 公平点Controller 没有this.disposed = true;(只有GC.SuppressFinalize(this))...也仍然不确定您期望派生类实现的样子。
  • 两次调用GC.SuppressFinalize 有什么意义(因为基类已经这样做了)?
  • 只是澄清一下 - 你明白你在谈论 2 种不同的情况 - 派生类覆盖父类的 Dispose(bool)(在 DeptsController 的情况下)与为派生类提供虚拟方法的基类覆盖(在StudentRepository的情况下)?
  • @AlexeiLevenkov 好的,所以你的意思是最后调用 GC.SuppressFinalize(this);是多余的,因为基类 Controller 已经调用了它,并且当我调用它时 base.Dispose(disposing);在我的控制器中,GC 将被调用 ..

标签: c# asp.net asp.net-mvc asp.net-mvc-5 dispose


【解决方案1】:

如果您的类有一个~DeptsController 方法(也称为终结方法或“析构函数”),并且它所做的只是调用Dispose(),您需要调用GC.SuppressFinalize(this) 以防止Dispose 被调用两次。

如果你的类没有析构函数,那就没有必要了。

【讨论】:

  • 虽然有合理的建议,但您可能想说“如果基类...”而不是您当前的答案,因为 OP 在示例中显示 override
  • @John 感谢您的回复。现在我的 Controller 类没有任何析构函数
  • @johnG 无论 John Wu 所说,仅适用于在密封类上直接实现 Dispose,如果类未密封,则无法阻止派生类具有析构函数,因此在您的帖子中显示模式base 抑制最终确定始终是必要的。
【解决方案2】:

当您实现 IDisposble 时,只需使用 Visual Studio 将构建的实现即可。生成的代码中的 cmets 会准确地告诉您何时需要调用 GC,何时不需要调用 GC。生成代码示例:

        private bool disposedValue = false; // To detect redundant calls

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                // TODO: dispose managed state (managed objects).
            }

            // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
            // TODO: set large fields to null.

            disposedValue = true;
        }
    }

    // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
    // ~ChampionGgCallerHttpClient() {
    //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
    //   Dispose(false);
    // }

    // This code added to correctly implement the disposable pattern.
    public void Dispose()
    {
        // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
        Dispose(true);
        // TODO: uncomment the following line if the finalizer is overridden above.
        // GC.SuppressFinalize(this);
    }

【讨论】:

    猜你喜欢
    • 2012-04-14
    • 2010-12-14
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多