垃圾回收 - 是否需要

本文关键字:是否 | 更新日期: 2023-09-27 18:31:40

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

System.Timers.Timer允许 IDisposable 接口,因此"using"是一个选项,但不在以下选项中,因为计时器的范围需要扩展到订阅计时器已用事件的方法myTimer_Elapsed。我已经尝试了两次垃圾收集,但都失败了,因为计时器没有闲逛足够长的时间!

出于其他原因,我之前在 这里

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();}
    }
}

垃圾回收 - 是否需要

唯一要释放计时器资源的地方是在回调函数 myTimer_Elapsed 中。你做myTime.Stop();的地方你也可以做myTimer.Dispose();

但是,当应用程序的这一部分超出范围时,所有这些变量都将被清理。只要计时器最终停止,一旦取消引用,GC 就会收集它。

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

窗体的OnClosing事件上释放计时器,如果这不是主窗体,或者顺便说一下,始终可见的窗体。

伪代码可能如下所示:

public partial class AirportParking : Form
{
  .....
  .....
  protected override void OnClosing(...)
  {
       myTimer.Dispose();
  }
}

如果这是某种"长时间运行"的形式,您应该在不再需要它的那一刻添加时间的处置,但我想你已经知道了。

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

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