Нужно ли утилизировать System.Timers.Timer, если вы используете его в своем приложении? - PullRequest
37 голосов
/ 24 января 2009

Я использую класс System.Timers.Timer в одном из классов в моем приложении. Я знаю, что класс Timer имеет метод Dispose, унаследованный от родительского класса Component, который реализует интерфейс IDisposable. Экземпляры класса ниже создаются много раз в течение жизненного цикла моего приложения; у каждого из них есть экземпляр класса Timer, который непрерывно генерирует события Elapsed в течение жизненного цикла класса. Должен ли я реализовать интерфейс IDisposable в классе, который использует класс Timer для удаления объекта таймера? (Я видел код, который не делает этого вообще). Я боюсь, что некоторые неуправляемые ресурсы не будут освобождены, если я буду использовать приведенный ниже класс следующим образом:

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

Класс:

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;
            }
        }
    }
}

Ответы [ 7 ]

29 голосов
/ 24 января 2009

Вообще говоря, вы всегда должны распоряжаться одноразовыми ресурсами. Я, конечно, буду искать в случае, если вы изложите выше. Если вы реализуете IDisposable в классе, который реализует таймер, вы можете затем использовать класс в операторе using, то есть ресурсы будут явно освобождены при удалении вашего класса.

20 голосов
/ 21 мая 2010

Я вижу, что вы задавали этот вопрос год назад, но позвольте мне добавить мои 2 цента. Чуть меньше из-за инфляции :). Недавно я обнаружил в нашем приложении, что мы не избавляемся от таймеров. У нас была коллекция объектов, и у каждого объекта был таймер. Когда мы удалили элемент из коллекции, мы подумали, что это должен быть мусор. Почему-то не так с таймерами. Мы должны были вызвать dispose для объекта в коллекции, чтобы избавиться от таймера, прежде чем объекты были фактически собраны мусором.

5 голосов
/ 24 января 2009

Эмпирическое правило, которое я использую, заключается в создании всего, что имеет объект IDisposable, сам IDisposable (и удаление дочерних объектов только при явном вызове Dispose)

Хорошее обсуждение IDisposable можно найти на в блоге Джо Даффи вместе с примерами кода, которые очень похожи на примеры из моей копии превосходной Framework Design Guidelines book

4 голосов
/ 25 ноября 2010

Таймер должен быть утилизирован, иначе он будет работать еще некоторое время после того, как вы «покончили» с ним. Однако из-за проблем с потоками он может все еще срабатывать через короткое время после его удаления!

2 голосов
/ 24 января 2009

Реализуя idisposable, вы сможете привести в порядок любые внутренние ресурсы, которые также реализуют unisposable, такие как ваш таймер.

Кроме того, вы сможете изменить свой код вызова для использования статистики использования.

using (SomeClass someClass = new SomeClass())
{  
someClass.DoSomething();  
}  
2 голосов
/ 24 января 2009

Я бы предположил, что объект таймера создает или использует рабочий поток для запуска событий таймера. Вызов dispose освободит поток и связанные с ним ресурсы. Если это так, было бы неплохо вызвать dispose, чтобы у вас не было слишком длинных неиспользуемых потоков.

1 голос
/ 29 апреля 2009

Я согласен с Роулендом.

В FxCop существует правило, которое находит классы, содержащие одноразовые объекты, но неправильно реализует IDisposable.

...