我有一个类,这个类的“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();
}
}
所以我想问,如果我这样做,会有任何问题吗?我的对象将被处理?有什么最好的方法吗?谢谢!
答案 0 :(得分:8)
这是对Dispose()
的不当使用。
Dispose()
适用于两种情况:
IDisposable
的类型的对象时。您应该将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的许多实现都有额外的逻辑来控制对象是否已被释放,以及处理对象时的事件。此事件通常用于从已添加到的集合中删除对象。
当垃圾收集器回收它时,对象本身才会停止存在。