垃圾收集 - 是否需要?

时间:2012-04-18 07:19:34

标签: c# winforms garbage-collection

一般来说,垃圾收集是一种很好的做法,因为它可以释放资源。 如何在以下代码的keepingTime方法中实现正确的垃圾收集?或者,事实上,我甚至需要吗?!

System.Timers.Timer允许IDisposable接口,因此'using'是一个选项,但不在下面,因为定时器的范围需要扩展到订阅Timer Elapsed事件的方法myTimer_Elapsed。我已经进行了两次垃圾收集尝试,但都失败了,因为计时器不会长时间停留!

我之前在HERE

中讨论了此代码,出于其他原因
public partial class AirportParking : Form
{

    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //instance variables of the form
    System.Timers.Timer myTimer;

    private const string EvenText = "hello";
    private const string OddText = "hello world";

    static int tickLength = 100; 
    static int elapsedCounter;
    private int MaxTime = 5000;
    private TimeSpan elapsedTime; 
    private readonly DateTime startTime = DateTime.Now; 
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


    public AirportParking()
    {
        InitializeComponent();
        lblValue.Text = EvenText;
        keepingTime();
    }

    //method for keeping time
    public void keepingTime() {

        myTimer = new System.Timers.Timer(tickLength);
        myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
        myTimer.AutoReset = true;
        myTimer.Enabled = true;
        myTimer.Start();

        //ATTEMPT_1.tried the following unsuccessfully
        //using (System.Timers.Timer myTimer = new System.Timers.Timer(tickLength))
        //{
        //    myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
        //    myTimer.AutoReset = true;
        //    myTimer.Enabled = true;
        //    myTimer.Start();
        //}

        //ATTEMPT_2.tried the following unsuccessfully
        //myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
        //myTimer.AutoReset = true;
        //myTimer.Enabled = true;           
        //try
        //{
        //    myTimer.Start();
        //}
        //finally
        //{
        //    myTimer.Dispose();
        //}

    }

    private void myTimer_Elapsed(Object myObject,EventArgs myEventArgs){

        elapsedCounter++;
        elapsedTime = DateTime.Now.Subtract(startTime);

        if (elapsedTime.TotalMilliseconds < MaxTime)
        {
            this.BeginInvoke(new MethodInvoker(delegate
            {
                this.lblElapsedTime.Text = elapsedTime.ToString();

                if (elapsedCounter % 2 == 0)
                    this.lblValue.Text = EvenText;
                else
                    this.lblValue.Text = OddText;
            }));
        }
        else {myTimer.Stop();}
    }
}

3 个答案:

答案 0 :(得分:2)

在Form的OnClosing事件上处理您的计时器,如果这不是主表单,或顺便说一下,表示始终可见的表单。

伪代码可能如下所示:

public partial class AirportParking : Form
{
  .....
  .....

  protected override void OnClosing(...)
  {
       myTimer.Dispose();
  }
}

如果这是一个“长时间运行”的形式,你应该在你不再需要的时候添加时间表的处理,但我想你已经知道了。

答案 1 :(得分:2)

您唯一想要处理计时器资源的地方是回调函数myTimer_Elapsed。您myTime.Stop();的所在地,也可以myTimer.Dispose();

但是,当应用程序的这部分超出范围时,无论如何都将清除所有这些变量。只要计时器最终停止,一旦它被解除引用,它将被GC收集。

using阻止(以及您当前的Dispose())不起作用的原因是您在创建计时器后立即丢弃计时器!你必须让它在后台运行。

答案 2 :(得分:1)

尽管垃圾收集是一种很好的做法,但在这种情况下,当您关闭表单或实例死亡时,它会自动完成。

我唯一真正担心的是SQL阅读器,因为你必须确保它们在你完成后关闭,否则会导致各种各样的问题。