Dispose 中的 GC.Collect() 简单类

Posted

技术标签:

【中文标题】Dispose 中的 GC.Collect() 简单类【英文标题】:GC.Collect() in Dispose in simple class 【发布时间】:2022-01-10 22:33:03 【问题描述】:

我在c#中继承了一种古老的网站项目。它起源于2003年 这到处都定义了从 IDisposible 继承并实现 Dispose() 方法的简单类,其中 GC.Collect() 被调用如下:

public class ProjectAutostart : IDisposable

    public void Dispose()
    
        Dispose(true);
        GC.Collect();
    
    protected virtual void Dispose(bool disposing)  
    private Int32 _id;
    private Int32 _stepid;
    private Int64 _stepcounter;

    public Int32 ID
    
        set  _id = value; 
        get  return _id; 
    
    public Int32 StepID
    
        set  _stepid = value; 
        get  return _stepid; 
    
    public Int64 StepCounter
    
        set  _stepcounter = value; 
        get  return _stepcounter; 
    

这些类的名称如下:

List<Projects.ProjectAutostart> ProjectList = DataLayer.Projects.getProjectAutoStart();

最后是:

public static List<Projects.ProjectAutostart> getProjectAutoStart()

    List<Projects.ProjectAutostart> Projects = new List<Projects.ProjectAutostart>();
    DataTable DataTable = SQL.DataTable("getProjectAutoStart", null);
    foreach (DataRow dt in DataTable.Rows)
    
        Projects.Add(new ProjectAutostart  ID = Convert.ToInt32(dt["projectid"]), StepID = Convert.ToInt32(dt["stepid"]), StepCounter = Convert.ToInt32(e["autostartstepcounter"]) );
    
    DataTable.Dispose();
    return Projects;

我对这种类型的项目没有经验,我完全进入了 .net 核心 restfull 领域,所以这段代码对我来说很奇怪。 除了完全奇怪的实现方式之外,这些 GC.Collect() 和 Dispose() 感觉完全没用,因为它是托管代码并且它是简单的类,没有任何编码执行。为什么有人会把 Dispose 和 GC.Collect() 放在那里? 我应该删除它吗?

【问题讨论】:

对我来说似乎是一种反模式。它没有任何用处 - 我只是删除所有无用的代码。 我同意马修的观点。删除垃圾代码是一个健康的过程。 (而且非常充实,我可能会补充) 更好的是,提交给thedailywtf.com,让大家开怀大笑 此外,SQL 查询可能应该重构为使用 Dapper,或者至少直接从 Reader 读取到新对象中。 Convert.ToInt32 应该是演员 (int) 【参考方案1】:

正如 cmets 中已经指出的,Dispose 方法中的GC.Collect() 在这里完全是多余的。也许他们一开始就弄错了 dispose 模式。

dispose 模式的推荐实现如下:

    public void Dispose()
    
        Dispose(true);
        GC.SuppressFinalize(this); // sic!
    
    protected virtual void Dispose(bool disposing) 
    
    

但是,由于您的 ProjectAutostart 类是纯 DTO 并且没有任何一次性字段(并且任何派生类也可能没有),因此您甚至不需要在此处实现 dispose。只需删除 Dispose 方法和接口声明即可。您需要处理的是DataTable 对象,但这已经正确完成了。

【讨论】:

以上是关于Dispose 中的 GC.Collect() 简单类的主要内容,如果未能解决你的问题,请参考以下文章

在python中使用gc.collect()清除内存对缓存数据的queue队列是否有影响

unity中gc.collect和resources.unloadunusedassets功能有啥异同

垃圾收集器是否受益于对Collect和WaitForPendingFinalizers()的多次调用?

内存泄漏处理Xamarin.Forms

c# 释放socket 端口

C#编写的WinForm程序,运行一段时间后越来越卡,怎么办?