G
Guest
I believe I ran into an interesting way to create memory leaks in C# 2.0
using anymous delegates. Here is a sample of the code in question.
private void Handle_Event(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 10000;
NotifyForm notifyForm = new notifyForm();
notifyForm.Show();
timer.Tick += delegate(object timerSender, EventArgs tArgs)
{
notifyForm.Close();
notifyForm.Dispose();
timer.Stop();
};
timer.Start();
}
The above code is responding to an event, displaying a Form to notify the
user of the completed event and closing the Form in 10 seconds. The
potential issue I see is I assign an anonymous delegate into the timer's Tick
event. The timer's Tick event now has a reference to my anonymous delegate.
According to Anders Heilsbergs book on C# 2.0 the timer reference will now be
captured and will not be released until after the anonymous delegate has been
garbage collected, but in the above example the anonymous delegate cannot be
collected , because the Timer's Tick event has a reference to it. Is this
analysis of this code correct? If so what suggestions do you have to get
around this. I have my own suggestion, it goes something this (I really have
to credit my co-worker Mike for this suggestion):
private void Handle_Event(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 10000;
NotifyForm notifyForm = new notifyForm();
notifyForm.Show();
//Initializing the handler variable to null allows it to be accessed
inside of the
//anonymous delegate.
EventHandler handler = null;
handler = delegate(object timerSender, EventArgs tArgs)
{
notifyForm.Close();
notifyForm.Dispose();
timer.Stop();
timer.Tick -= handler;
} ;
timer.Tick += handler;
timer.Start();
}
The idea in the above example being that the anonymous delegate is assigned
into a local variable which can be accessed inside of the anonymous delegate.
By doing this I can unsubscribe from the Tick event allowing the delegate to
garbage collected, and consequently the Timer instance can also be garbage
collected. Does this solve the issues of the memory leak? Is there a better
way to solve this issue? Thank you.
using anymous delegates. Here is a sample of the code in question.
private void Handle_Event(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 10000;
NotifyForm notifyForm = new notifyForm();
notifyForm.Show();
timer.Tick += delegate(object timerSender, EventArgs tArgs)
{
notifyForm.Close();
notifyForm.Dispose();
timer.Stop();
};
timer.Start();
}
The above code is responding to an event, displaying a Form to notify the
user of the completed event and closing the Form in 10 seconds. The
potential issue I see is I assign an anonymous delegate into the timer's Tick
event. The timer's Tick event now has a reference to my anonymous delegate.
According to Anders Heilsbergs book on C# 2.0 the timer reference will now be
captured and will not be released until after the anonymous delegate has been
garbage collected, but in the above example the anonymous delegate cannot be
collected , because the Timer's Tick event has a reference to it. Is this
analysis of this code correct? If so what suggestions do you have to get
around this. I have my own suggestion, it goes something this (I really have
to credit my co-worker Mike for this suggestion):
private void Handle_Event(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 10000;
NotifyForm notifyForm = new notifyForm();
notifyForm.Show();
//Initializing the handler variable to null allows it to be accessed
inside of the
//anonymous delegate.
EventHandler handler = null;
handler = delegate(object timerSender, EventArgs tArgs)
{
notifyForm.Close();
notifyForm.Dispose();
timer.Stop();
timer.Tick -= handler;
} ;
timer.Tick += handler;
timer.Start();
}
The idea in the above example being that the anonymous delegate is assigned
into a local variable which can be accessed inside of the anonymous delegate.
By doing this I can unsubscribe from the Tick event allowing the delegate to
garbage collected, and consequently the Timer instance can also be garbage
collected. Does this solve the issues of the memory leak? Is there a better
way to solve this issue? Thank you.