C# ValueType未收集垃圾?
在click事件返回后,我期望Dispose调用,但这从未发生过,有人可以解释一下。我不想执行任何手动步骤,如调用Dispose或使用。我希望这能自动发生 谢谢你的回答,我想为LocalDataStoreSlot实现一个a类,它会自动释放插槽,并且超出范围,如注释代码所示。这将使开发人员不必记住C# ValueType未收集垃圾?,c#,collections,garbage,C#,Collections,Garbage,在click事件返回后,我期望Dispose调用,但这从未发生过,有人可以解释一下。我不想执行任何手动步骤,如调用Dispose或使用。我希望这能自动发生 谢谢你的回答,我想为LocalDataStoreSlot实现一个a类,它会自动释放插槽,并且超出范围,如注释代码所示。这将使开发人员不必记住 调用dispose,其中实际的FreeNamedDataSlot(…)发生。似乎这是不可能的您必须像这样使用将对象声明包装在中: public struct LocalTLS : IDisposabl
调用dispose,其中实际的FreeNamedDataSlot(…)发生。似乎这是不可能的您必须像这样使用将对象声明包装在
中:
public struct LocalTLS : IDisposable
{
public byte[] bArr;
public string str;
public LocalTLS(int k)
{
str = "Labamba";
bArr = new byte[20000];
}
public void Dispose()
{
MessageBox.Show("In Dispose");
//Thread.FreeNamedDataSlot("jaja");
int k = 90;
k += 90;
}
}
private void buttonTLS_retreive_Click(object sender, EventArgs e)
{
LocalTLS lts = new LocalTLS(1);
}
或手动调用Dispose
方法:
using(LocalTLS lts = new LocalTLS(1))
{
// use lts here
} // at this point, the Dispose method is called.
另外,当代码中没有对lts
的引用时,垃圾收集器会自动调用Dispose()
方法。它是一个结构,它位于内存堆栈而不是内存堆上。所以它不会像对象那样被车库收集器收集,所以GC不会调用dispose方法。当方法结束时,您的结构“LocalTLS”将被释放并从内存堆栈中移除。执行此操作时,它不会查找IDisposable接口。CLR不会一直执行垃圾收集,否则您的程序将非常慢,因为它正在执行GC。要执行GC,CLR必须先挂起所有线程,然后才能回收范围外对象使用的内存。这对性能有很大的影响
CLR将执行GC并在必要时调用对象的Dispose方法。除非有充分的理由,否则不要调用对象的Dispose()方法。如果对象与本机系统句柄、网络连接、文件句柄等相关联,则这些都是使用using
关键字或调用其Dispose()
方法的好理由。通常,CLR将以足够快的速度处理超出范围的GC对象,这样应用程序就不会耗尽内存
我理解您的担忧,您认为字节[20000]对应用程序来说是一个重要的内存占用,您希望仔细控制内存使用。但这不是C++。CLR将自动为您管理内存。在我过去7年的.NET开发中,我只遇到过一个应用程序,其中默认GC不够快,我必须手动调用对象上的Dispose()。因此,简而言之,只需将内存管理交给CLR即可-它做得非常好
p、 如果你对GC的内部工作方式感兴趣,网上有很多深入的文章。只需搜索-您就会找到它们。这里是我唯一的后续问题:您知道何时以及如何使用IDisposable
?你能解释一下为什么期望在事件返回后调用Dispose方法吗?我期望Dispose调用,但这永远不会发生-预期的行为,你的期望是错误的=当lts超出范围时,不会自动调用DDispose()。可以手动调用它,也可以将它包装在“using”块中。如果我不想使用using(因为我可以修改它),该怎么办values@Dr.sai,请参阅我答案的最后一行,我也不想打电话给dispose,如果Microsoft说它们将自动收集,那么我希望在dispose上打电话,ThanksNope dispose从未被调用,因为消息框从未被调用comes@Dr.sai这就是埃米特想告诉你的——它不会被叫来的。您需要使用using
块或自己调用它。这就是它的工作原理。它不是析构函数。
lts.Dispose();