In general it’s good practice to garbage collect as it frees up resources.
How do I implement correct garbage collection in the following code’s keepingTime method? Or, in fact, do I even need to?!
System.Timers.Timer allows IDisposable interface so ‘using’ is an option, but not in the following as the scope of the timer needs to extend to the method myTimer_Elapsed that is subscribed to the Timer Elapsed event. I’ve made two attempts to garbage collect but both fail as the timer does not then hang around long enough!
I’ve previously dicussed this code, for other reasons, in 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();}
}
}
The only place you’ll want to dispose of the timer resource is in the callback function
myTimer_Elapsed. Where you domyTime.Stop();you can also domyTimer.Dispose();.However, when this part of the application goes out of scope, all these variables will be cleaned up anyway. As long as the timer is eventually stopped, once it’s dereferenced it will be collected by the GC.
The reason the
usingblocks (and your currentDispose()) doesn’t work is that you’re throwing away the timer as soon as you create it! You have to let it run in the background.