0

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

System.Timers.Timer允许 IDisposable 接口,所以 'using' 是一个选项,但不是在下面,因为计时器的范围需要扩展到myTimer_Elapsed订阅 Timer 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();}
    }
}
4

3 回答 3

2

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

伪代码可能如下所示:

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

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

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

于 2012-04-18T07:24:04.380 回答
2

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

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

using块(和你的 current Dispose())不起作用的原因是你一创建计时器就扔掉它!你必须让它在后台运行。

于 2012-04-18T07:25:26.080 回答
1

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

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

于 2012-04-18T10:05:34.367 回答