Lambdas in extension methods: Possible memory leak?

I just answered a fairly simple question using the extension method. But after writing it, I remembered that you cannot unsubscribe from a lambda from an event handler.

There is still no big problem. But how does all this behave in the extension method?

Below my code is disabled again. So can someone enlighten me if this leads to a lot of timers hanging in memory if you call this extension method several times?

I would say no, because the scope of the timer is limited by this function. Therefore, leaving it, no one has a link to this object. I am just a little sure, because we are here in a static function in a static class.

public static class LabelExtensions
{
    public static Label BlinkText(this Label label, int duration)
    {
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        timer.Interval = duration;
        timer.Tick += (sender, e) =>
            {
                timer.Stop();
                label.Font = new Font(label.Font, label.Font.Style ^ FontStyle.Bold);
            };

        label.Font = new Font(label.Font, label.Font.Style | FontStyle.Bold);
        timer.Start();

        return label;
    }
}

Update

, System.Windows.Forms.Timer. , , , . , , . , WeakReference, .

2

() GC.Collect() 10000. BlinkText() 2, . , , , Stop(). , BlinkText , , .

, , , , , .

+5
7

, , . //timer.Stop();, , GC.Collect();.

WM_ - . (Enabled = false), .
static extension method .

+2

. timer .

lamba ( , ) .

, / , .

+4

. . , , , . , MyTimer Timer, Dispose (bool) . , BlinkText GC.Collect GC.WaitForPendingFinalizers. .

+2

, @cornerback84. . , GC.Collect(). timer.Stop() . . .

/ ... Timer - , .

Edit:...

... Timer.

  • System.Windows.Forms.Timer = > this , . .Stop(), .

  • System.Timers.Timer = > . Yout . . .Stop(), .

  • System.Threading.Timer = > . GC.Collect() ( , , )

+1

, . , , .

0

, Dispose , Stop , .

0

, .

Extension :

public static class LabelExtensions
{
    public static List<WeakReference> _References = new List<WeakReference>();

    public static Label BlinkText(this Label label, int duration)
    {
        Timer timer = new Timer();

        _References.Add(new WeakReference(timer));

        timer.Interval = duration;
        timer.Tick += (sender, e) =>
        {
            timer.Stop();
            label.Font = new Font(label.Font, label.Font.Style ^ FontStyle.Bold);
        };

        label.Font = new Font(label.Font, label.Font.Style | FontStyle.Bold);
        timer.Start();

        return label;
    }
}

, click:

    private void button2_Click(object sender, EventArgs e)
    {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < LabelExtensions._References.Count; i++)
        {
            var wr = LabelExtensions._References[i];
            sb.AppendLine(i + " alive: " + wr.IsAlive);
        }

        label2.Text = sb.ToString();
    }

Now I just pressed the first button several times so that the first mark blinked. Then I pressed the second button and got a list where I can see if all my timers are still alive. At the first click, they got the truth. But then I pressed my first button again and, updating the status message, I saw that the first elements had already received a lie in IsAlive. Therefore, I can say with confidence that this function does not lead to memory problems.

0
source

All Articles