6

Is it safe to do something like this:

private void MyFunction()
{
    DispatcherTimer timer = new DispatcherTimer();
    timer.Interval = new TimeSpan(0, 0, 1);
    timer.Tick += (object sender, object e) =>
    {
        timer.Stop();
        // Some code here
    };
    timer.Start();
}
K Mehta
  • 10,323
  • 4
  • 46
  • 76
  • 1
    You should be more specific about what you mean by "safe"... – H.B. Oct 22 '11 at 01:15
  • @H.B. I left it generic because I'm not sure what can potentially go wrong with using anonymous methods like this. If I knew, I would've just researched it myself :) – K Mehta Oct 22 '11 at 01:50

3 Answers3

6

Matt raise the point that the way you attach the anonymous method that there is no easy way to detach it. Here is a general pattern you can use to enable you to detach if necessary.

private void MyFunction()
{
    DispatcherTimer timer = new DispatcherTimer();
    timer.Interval = new TimeSpan(0, 0, 1);
    EventHandler eh = null;
    eh = (object sender, object e) =>
    {
        timer.Tick -= eh;
        timer.Stop();
        // Some code here
    };

    timer.Tick += eh;
    timer.Start();
}

However in this specific case there is nothing wrong with the way your original code works since the timer becomes collectable as soon as it is stopped.

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
4

Yes. Your timer will fire once.

driis
  • 161,458
  • 45
  • 265
  • 341
  • Isn't this a memory leak? With no corresponding timer.Tick -= , won't the surrounding object never get garbage collected due to the timer's reference to this delegate? – Matt Bridges Oct 22 '11 at 00:33
  • @MattBridges: If there is no reference to the timer it does not matter how much of a "tail" it has, it should be collected as far as i know. – H.B. Oct 22 '11 at 01:14
  • Ah, right. I still shy away from anonymous delegates as event handlers as a rule though. – Matt Bridges Oct 22 '11 at 01:16
2

Edit: I'll rephrase my answer based on the comments. In the situation you've given, yes it's perfectly safe to use an anonymous delegate.

There are some situations in which adding an anonymous delegate and not detaching it could prevent your class from being garbage collected (for example, attaching an anonymous delegate to a singleton). See this answer for information about when it is and isn't necessary to detach the event handler.

Community
  • 1
  • 1
Matt Bridges
  • 48,277
  • 7
  • 47
  • 61
  • 2
    It's not a bad habit unless you need to detach. In many cases you don't: the timer will become unreferenced and the timer and anon delegate will be collected. Avoiding anon function like this doesn't magically make your code more memory safe - detaching the handler is what makes it safe. You can still forget to do that with non-anon delegates. You need to understand what you're doing in any case. – Grokys Oct 22 '11 at 15:01
  • In the end it's a matter of style -- I tend to stay away from it because I've been bitten before by unexpected memory leaks. "It's not a bad habit unless you need to detach" is like saying "Speeding is not a bad habit unless you get a ticket." – Matt Bridges Oct 22 '11 at 15:12
  • Ha, how about "not wearing pants at home is ok, but remember to put them on when you go outside" ;) But yes I get your point - it's a matter of preference/style. – Grokys Oct 22 '11 at 15:47
  • 1
    Matt "matters of style" are one thing but offering such advice as the primary focus of your answer using words such as "bad habit" elevates this matter of style more than it ought. Personaly I find such use of anonymous functions enormously beneficial, it tends to keep a specific task all in one place and often avoids the need to create additional classes to hold any state needed between events/callbacks. – AnthonyWJones Oct 22 '11 at 16:13
  • +1 for letting me know when it _is_ unsafe to have an anonymous delegate – K Mehta Oct 22 '11 at 19:33