2014-05-09 26 views
0
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或使用。我希望自动发生。ValueType未收集垃圾?

非常感谢您的回答,我想实现一个LocalDataStoreSlot的类,它将自动释放Slot并超出范围,如注释代码所示。这将使开发者免于记忆到 调用处理,其中实际的FreeNamedDataSlot(...)发生。好像这是不可能的

+3

这是我唯一的后续问题:你知道何时以及如何使用'IDisposable'吗? [这是一个链接,以防万一](http://msdn.microsoft.com/en-us/library/system.idisposable.aspx) –

+1

你能解释为什么你期望在事件返回后调用Dispose方法吗? –

+0

*我期待Dispose调用,但从未发生过* - 预期的行为,您的期望完全错误。 = D – Sinatr

回答

0

您对包装你的对象声明中using这样的:

using(LocalTLS lts = new LocalTLS(1)) 
{ 
    // use lts here 

} // at this point, the Dispose method is called. 

或致电手动Dispose方法:

lts.Dispose(); 

此外,Dispose()方法是自动当垃圾收集器没有在代码中引用lts时调用。

+0

如果我不想使用,因为我可以修改值 –

+0

@Dr。sai,看到我的答案的最后一行 –

+0

我也不想调用dispose,如果微软说他们会自动收集,那么我期望在Dispose上打一个电话,谢谢 –

0

它是一个结构体,它位于内存堆栈而不是内存堆。所以它不会像对象一样被车库收集器收集,所以GC不会调用dispose方法。当你的方法结束时,你的struct“LocalTLS”将被释放并从内存栈中取出。当它这样做时,它不会查找IDisposable接口。

1

CLR不会一直执行垃圾回收,否则你的程序会很慢,因为它正在执行GC。为了执行GC,CLR必须在回收超出范围对象使用的内存之前挂起所有线程。这是一个非常大的性能影响。

CLR将执行GC并在必要时调用对象的Dispose方法。除非你有充分的理由,否则不要调用对象的Dispose()方法。如果该对象与本地系统句柄,网络连接,文件句柄等相关联,那么使用using关键字或将其称为Dispose()方法是很好的理由。通常,CLR将超出范围的GC对象足够快,以至于应用程序不会耗尽内存。

我明白你的关注,你认为字节[20000]是一个重要的内存足迹到你的应用程序,你想仔细控制你的内存使用情况。但这不是C++。 CLR将自动为您管理内存。在过去7年的.NET开发中,我只遇到一个应用程序,默认的GC不够快,我不得不手动调用Dispose()。总而言之,只需将内存管理移交给CLR--它的工作非常出色。

p.s.如果您对GC的内部工作方式感兴趣,可以在线获取许多深入的文章。只要搜索 - 你会找到它们。