我遇到了内存泄漏问题,我想知道是否有人可以告诉我我做错了什么(或者我错过了什么微软错误)。下面是一个演示此问题的示例应用程序。调用TestCollectTimer.Test()来运行示例。
问题是,无论有多少" MyTimerData"创建或调用GC.Collect()的次数,在应用程序关闭之前永远不会调用MyTimerData的终结器。
class TestCollectTimer
{
public static void Test()
{
for (int index_A = 0; index_A < 100000; index_A++)
{
MyTimerData mtd = new MyTimerData();
mtd = null;
}
GC.Collect();
Thread.Sleep(2000);
GC.Collect();
Form f = new Form();
f.ShowDialog();
}
}
class MyTimerData
{
public System.Threading.Timer m_timer;
public MyTimerData()
{
this.m_timer = new System.Threading.Timer(
new System.Threading.TimerCallback(this.TimerCall),
null,
System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
}
~MyTimerData()
{
MessageBox.Show("Collect My Timer Data");
}
public void TimerCall(object o) { }
}
谢谢你的帮助
答案 0 :(得分:2)
在调试模式下,所有局部变量&#39;范围被人为地扩展到其封闭方法的末尾,因此在您完成在调试器中检查它们之前,它们不会被收集。
在Release模式下编译时,您的代码按预期工作,并且在没有附加调试器的情况下运行。
您也可以将for循环移动到自己的方法中,然后即使在调试模式下,您的计时器也可以在返回后进行收集。
答案 1 :(得分:0)
处理你的计时器怎么样?
class TestCollectTimer
{
public static void Test()
{
for (int index_A = 0; index_A < 100000; index_A++)
{
using(MyTimerData mtd = new MyTimerData())
{
//do your stuff here
}
}
GC.Collect();
Form f = new Form();
f.ShowDialog();
}
}
class MyTimerData : IDisposable
{
public System.Threading.Timer m_timer;
public MyTimerData()
{
this.m_timer = new System.Threading.Timer(
new System.Threading.TimerCallback(this.TimerCall),
null,
System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
}
public void TimerCall(object o) { }
public void Dispose()
{
Dispose(true);
}
protected void Dispose(bool disposing)
{
m_timer.Dispose();
GC.SuppressFinalize(this);
}
}
您可以查看规则CA1001:http://msdn.microsoft.com/en-us/library/ms182172.aspx