C# ValueType未收集垃圾?

C# ValueType未收集垃圾?,c#,collections,garbage,C#,Collections,Garbage,在click事件返回后,我期望Dispose调用,但这从未发生过,有人可以解释一下。我不想执行任何手动步骤,如调用Dispose或使用。我希望这能自动发生 谢谢你的回答,我想为LocalDataStoreSlot实现一个a类,它会自动释放插槽,并且超出范围,如注释代码所示。这将使开发人员不必记住 调用dispose,其中实际的FreeNamedDataSlot(…)发生。似乎这是不可能的您必须像这样使用将对象声明包装在中: public struct LocalTLS : IDisposabl

在click事件返回后,我期望Dispose调用,但这从未发生过,有人可以解释一下。我不想执行任何手动步骤,如调用Dispose或使用。我希望这能自动发生

谢谢你的回答,我想为LocalDataStoreSlot实现一个a类,它会自动释放插槽,并且超出范围,如注释代码所示。这将使开发人员不必记住
调用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();