Reputation: 35557
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();}
}
}
Upvotes: 0
Views: 181
Reputation: 11
Although it is good practice to garbage collect, in this instance it would be would be done automatically when you close the form or the instance dies.
The only time I really worry about this is with SQL readers as you have to make sure they are closed off when you are finished otherwise it causes all sorts of problems.
Upvotes: 1
Reputation: 15618
The only place you'll want to dispose of the timer resource is in the callback function myTimer_Elapsed
. Where you do myTime.Stop();
you can also do myTimer.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 using
blocks (and your current Dispose()
) 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.
Upvotes: 2
Reputation: 62246
Dispose your timer on Form's OnClosing
event, if this is not a main form, or by the way, a Form that always visible.
A pseudocode can look like this:
public partial class AirportParking : Form
{
.....
.....
protected override void OnClosing(...)
{
myTimer.Dispose();
}
}
If this is some "long-running" form, you should add disposal of the timere at the moment you no more need it, but I think you already know that.
Upvotes: 2