Is it necessary to dispose System.Timers.Timer if

2019-01-11 08:47发布

问题:

I am using System.Timers.Timer class in one of the classes in my application. I know that Timer class has Dispose method inherited from the parent Component class that implements IDisposable interface. Instances of the class below are created many times during my application lifecycle; each of them has an instance of Timer class that generates Elapsed events continuously during the class's lifecycle. Should I implement IDisposable interface in the class that uses Timer class to dispose the timer object? (I have seen code that doesn't do this at all). I am afraid that some unmanaged resources will not be freed if I use the class below like this:

SomeClass someClass = new SomeClass();
someClass.DoSomething();
someClass = null;

The class:

using System.Timers;

public class SomeClass
{
    private Timer m_timer;

    public SomeClass()
    {           
        m_timer = new Timer();
        m_timer.Interval = 1000;
        m_timer.Elapsed += new ElapsedEventHandler(m_timer_Elapsed);
        m_timer.AutoReset = false;
        m_timer.Start();                       
    }

    public void DoSomething()
    {

    }

    private void m_timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            //Do some task
        }
        catch (Exception ex)
        {
            //Ignore
        }
        finally
        {
            if (m_timer != null)
            {
                //Restart the timer
                m_timer.Enabled = true;
            }
        }
    }
}

回答1:

Generally speaking you should always dispose of disposable resources. I certainly would be looking to in the case you outline above. If you implement IDisposable on the class that implements the timer you can then use the class in a using statement, meaning resources will be explicitly released when your class is disposed.



回答2:

I see that you asked this question a year ago but let me throw in my 2 cents worth. Slightly less because of inflation :). Recently I discovered in our application that we weren't disposing of timers. We had a collection of objects and each object had a timer. When we removed the item from the collection we thought it should have been garbage collected. For some reason not so with timers. We had to call dispose on the object in the collection to get rid of the timer before the objects were actually garbage collected.



回答3:

The rule of thumb I use is to make anything that has an IDisposable object, IDisposable itself (and disposing the child objects only when Dispose is explicitly called)

There's a good discussion on IDisposable at Joe Duffy's blog along with code samples which look very similar to those in my copy of the excellent Framework Design Guidelines book



回答4:

The timer has to be disposed, or it will keep fireing for some time after you have "finished" with it. However due to thread issues, it may still fire a short time after you have disposed it!



回答5:

I would guess that the timer object creates or uses a worker thread for the purposes of firing the timer events. The dispose call will free the thread and the resources associated with it. If that is the case, it would be a good idea to call dispose so you don't have unused threads hanging around too long.



回答6:

By implementing idisposable you will be able to tidy up any internal resources that also implement idisposable such as your timer.

In addition you would be able to change your calling code to use the using statment.

using (SomeClass someClass = new SomeClass())
{  
someClass.DoSomething();  
}  


回答7:

I agree with Rowland.

There is a rule in FxCop that finds classes containing Disposable objects, but not properly implementing IDisposable.