C#在列表中使用后处理对象?

时间:2013-04-28 09:02:02

标签: c# dispose

我有一个类,这个类的“value”变量包含从文件读取的大数据:

 public class MyClass : IDisposable
{
    public string name {get; set;}
    public string value {get; set;} //I'm load huge data for this variable

    public MyClass(string name, string value)
    {
        this.name = name;
        this.value = value;
    }

    public void Execute()
    {
        Console.WriteLine(this.name + ":" + this.value);
    }

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

    protected virtual void Dispose(bool disposing)
    {                     
        if (disposing)
        {
            this.name = null;
            this.value = null;
        }                      
    }
}

我在列表中使用这个类是全局变量

List<MyClass> listQ = new List<MyClass>() { new MyClass("1", "BIGDATA1"),
            new MyClass("2", "BIGDATA2"),
            new MyClass("3", "BIGDATA3"),
            new MyClass("4", "BIGDATA4"),
            new MyClass("5", "BIGDATA5"),
            new MyClass("6", "BIGDATA6"),
        };

    private void FUC_Load(object sender, EventArgs e)
    {                        
        foreach (MyClass m in listQ)
        {
            m.Execute();
            m.Dispose();
        }                       
    } 

所以我想问,如果我这样做,会有任何问题吗?我的对象将被处理?有什么最好的方法吗?谢谢!

4 个答案:

答案 0 :(得分:8)

这是对Dispose()的不当使用。

Dispose()适用于两种情况:

  1. 当您处置非托管资源时。
  2. 当您处置自身实现IDisposable的类型的对象时。
  3. 您应该将Dispose()方法重命名为Clear(),以便更好地描述正在发生的事情。

    或者(我觉得在你的情况下可能会更好)你可以在迭代后将listQ引用设置为null。由于您在迭代它时会破坏它所拥有的数据,因此很明显您之后不需要这些数据。

    如果将listQ引用设置为null,则其所有内存(包括它所引用的所有对象的内存)将(最终)被垃圾收集,假设没有其他内容保存对这些对象的引用

    请注意,您必须确保将listQ的所有引用设置为null。 (当它们被声明为返回方法时,对堆栈的引用将自动消失,因此您不必担心这些。)

答案 1 :(得分:1)

我猜你真的很担心对象占用你的记忆。除非你使用非托管资源,比如访问网络或远程数据库资源,否则你不必这么做。因为这不是你的情况,运行时是智能的,应该免费在认为必要时提供资源。

.net运行时中的垃圾收集为您管理托管资源,您不应过于担心释放托管句柄。

当您的List引用超出范围或GC知道未使用此列表时,该对象将从内存中清除。

答案 2 :(得分:1)

如果可能,请使用Queue类而不是List。这样,当您出列队列时,您会自动从集合中删除该对象:

while(queueCollection.Count > 0) {
    MyClass obj = queueCollection.Dequeue();
    obj.Execute();
}

答案 3 :(得分:-1)

IDisposable接口用于确定性终结。

它最初只是一种释放非托管资源的方法,但现在通常也用于完成托管对象。

结束并不意味着释放对象。这只是你打算不再使用这个物体的表现。

如果您的对象支持打开/关闭,则表示您可以多次打开和关闭它。在这种情况下,Dispose应调用Close(或执行相同操作),但对象不再可用。

IDisposable的许多实现都有额外的逻辑来控制对象是否已被释放,以及处理对象时的事件。此事件通常用于从已添加到的集合中删除对象。

当垃圾收集器回收它时,对象本身才会停止存在。