简体   繁体   中英

System.Timers.Timer lifecycle

which is the right approach to use a System.Timers.Timer? I mean... I create the timer, set the interval and the method to be called on the Elapsed event.

double ms = 1000;
var t = new System.Timers.Timer(ms);
t.AutoReset = false;
t.Elapsed += (sender, e) =>  { runTask(); }; 
t.Start();   

What next? Should a call dispose on the Timer? I suppose I can't, or the Elapsed event will never occur. Should I register the Timer in some global variable to avoid to lose references to it and so the GC could dispose the timer before the Elapsed is called? And if so, how can I dispose the Timer once the Elapsed event has been handled (thus my task has been executed)?

If you are using Timers during a long running process (eg a web application or a windows service), if you don't want to get a memory leak, you need to ensure that you un-subscribe from the Timer's elapsed event handler if you want the garbage collector to be able to reclaim the memory allocated for the Timer object.

System.Timers.Timer implements IDisposable and the guidelines here are that if you have a class that implements IDisposable, any class that has a dependency on an object implementing IDisposable should implement IDisposable itself and call the objects Dispose() method when it itself is called.

A perfect example of this is indeed with System.Timers.Timer. This uses System.Threading.Timer underneath the covers and if you look in reflector you can see the following for the Dispose method on System.Timers.Timer

public void Dispose()
{
    this.timerBase.Dispose();
}

Here, timerBase is simply an instance of System.Threading.Timer and therefore the Dispose call cascades down to all dependencies of the class that implement IDisposable.

A short answer is you don't need to do anything. It will be collected by the Garbage Collector when function goes out of scope. If you want it available then declare it in class instead.


Usually when you declare a timer out in class level it is collected by GC when the Class is Disposed. However when you have your timer declare in a Function then the Timer still runs but if you are executing a very long process then GC can Aggressively Dispose it so you will need to use

 GC.KeepAlive(youtimer_Instance); 

Have a look at the end of the Timer's Documentatio n for reference to this scenario.

The Comments in the sample code says:

                    

You should call t.Stop() in the Close/Unload of your form/page or anywhere you seem fit. If you leave it running, it will utilize resources unnecessarily and also you might get exceptions while closing the application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM