开发者

System.Timers.Timer lifecycle

开发者 https://www.devze.com 2023-02-09 12:31 出处:网络
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.

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 e开发者_开发知识库xecuted)?


If you are using Timers during a long running process (e.g. 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 Documentation for reference to this scenario.

The Comments in the sample code says:


        Normally, the timer is declared at the class level,
        so that it stays in scope as long as it is needed.
        If the timer is declared in a long-running method,  
        KeepAlive must be used to prevent the JIT compiler 
        from allowing aggressive garbage collection to occur 
        before the method ends. 


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消