The warning tells you that the variables end
and start
stay alive as any of the lambdas inside this method stay alive.
Take a look at the short example
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
int i = 0;
Random g = new Random();
this.button1.Click += (sender, args) => this.label1.Text = i++.ToString();
this.button2.Click += (sender, args) => this.label1.Text = (g.Next() + i).ToString();
}
I get an "Implicitly captured closure: g" warning at the first lambda. It is telling me that g
cannot be garbage collected as long as the first lambda is in use.
The compiler generates a class for both lambda expressions and puts all variables in that class which are used in the lambda expressions.
So in my example g
and i
are held in the same class for execution of my delegates. If g
is a heavy object with a lot of resources left behind, the garbage collector couldn't reclaim it, because the reference in this class is still alive as long as any of the lambda expressions is in use. So this is a potential memory leak, and that is the reason for the R# warning.
@splintor
As in C# the anonymous methods are always stored in one class per method there are two ways to avoid this:
Use an instance method instead of an anonymous one.
Split the creation of the lambda expressions into two methods.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…