Threading.Timer阻止GC收集

时间:2014-07-22 03:10:19

标签: c#

我遇到了内存泄漏问题,我想知道是否有人可以告诉我我做错了什么(或者我错过了什么微软错误)。下面是一个演示此问题的示例应用程序。调用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) { }
}

谢谢你的帮助

2 个答案:

答案 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