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调用,但绝不会发生,有人可以解释一下。我不想做任何手动步骤,如调用Dispose或使用。我希望自动发生这种情况。
非常感谢您的所有答案,我想为LocalDataStoreSlot实现一个类,它将自动释放Slot并且超出范围,如注释代码所示。这将使开发人员免于记忆 call dispose,其中实际的FreeNamedDataSlot(...)发生。似乎这是不可能的
答案 0 :(得分:1)
CLR不会一直执行垃圾收集,否则您的程序会因为执行GC而非常慢。要执行GC,CLR必须在回收超出范围对象使用的内存之前挂起所有线程。这是一个非常大的性能影响。
CLR将执行GC并在必要时调用对象的Dispose方法。除非有充分的理由,否则不要调用对象的Dispose()方法。如果对象与本机系统句柄,网络连接,文件句柄等相关联,那么这些是使用using
关键字或调用它的Dispose()
方法的充分理由。通常,CLR会使GC对象的范围超出范围,这样您的应用程序就不会耗尽内存。
我理解您的担忧,您认为byte [20000]对您的应用程序来说是一个重要的内存占用空间,并且您希望仔细控制内存使用情况。但这不是C ++。 CLR将自动为您管理内存。在我过去7年的.NET开发中,我只遇到过一个默认GC不够快的应用程序,我必须手动调用对象上的Dispose()。所以简而言之,只需将内存管理移交给CLR - 它做得非常好。
P.S。如果您对GC的内部工作感兴趣,可以在线阅读一些深入的文章。只需搜索 - 你就会找到它们。
答案 1 :(得分:0)
你要将对象声明包装在using
中,如下所示:
using(LocalTLS lts = new LocalTLS(1))
{
// use lts here
} // at this point, the Dispose method is called.
或手动调用Dispose
方法:
lts.Dispose();
此外,垃圾收集器在代码中没有引用Dispose()
时会自动调用lts
方法。
答案 2 :(得分:0)
它是一个结构,它存在于内存堆栈而不是内存堆中。所以它不会像对象一样被车库收集器收集,因此GC不会调用dispose方法。当方法结束时,您的结构“LocalTLS”将被释放并从内存堆栈中取出。当它这样做时,它不会寻找IDisposable接口。