Таймер остановки предыдущих экземпляров внутри конструктора?

#c# #timer

#c# #таймер

Вопрос:

У меня есть объект foo с таймером внутри, который я хотел бы остановить после переназначения foo . Чтобы сделать это, прямо сейчас я делаю следующее

 var foo=new MyClass();

//Do stuff....

if (foo!=null){foo.timer.stop();}

foo=new MyClass();
  

Есть ли способ, которым я мог бы добавить такую логику внутри конструктора MyClass, или более элегантный / простой способ сделать это?

  public class MyClass
        {
            public DispatcherTimer timer = new DispatcherTimer();
            public MyClass()
            {
                timer.Interval = TimeSpan.FromMilliseconds(100);
                timer.Tick  = Timer_Tick;
            }
            private void Timer_Tick(object sender, EventArgs e)
            {
                Console.WriteLine("I tick!!");
            }
        }
  

Ответ №1:

Вы могли бы использовать финализатор, в этом случае это выглядело бы так:

 ~MyClass {
    timer.stop();
}
  

Комментарии:

1. Я пытался, но я думаю, что он не удаляет объект до тех пор, пока GC не захочет, что может быть не сразу

2. Вы могли бы реализовать IDisposable, а затем явно вызвать .dispose

3. да, я могу попробовать. Дело в том, что я обычно слышу на форумах, что не стоит заставлять GC утилизировать объекты. С другой стороны, мне все равно пришлось бы утилизировать объект прямо перед переназначением, что, по сути, я и делаю прямо сейчас

4. Правда, если вы не хотите ждать, пока GC придет и соберет, я не думаю, что то, что вы просите, возможно без вызова dispose . Однако, насколько я знаю, нет проблем с явным вызовом dispose для объектов.

5. То, что вы описали, — это таймер, который является общим для всех экземпляров. Сделайте таймер статическим . Теперь вы можете поместить код, который проверяет значение null и останавливает таймер в конструкторе.

Ответ №2:

Если вы хотите поместить логику в конструктор MyClass, вы можете:

 public class MyClass
{
    private readonly DispatcherTimer timer = new DispatcherTimer();

    public MyClass()
    {
        timer.Interval = TimeSpan.FromMilliseconds(100);
        timer.Tick  = Timer_Tick;
    }
    
    public MyClass(MyClass oldFoo) : MyClass()
    {
        oldFoo?.StopTimer();
    }
    
    public void StopTimer()
    {
        timer.Stop();
    }
    
    private void Timer_Tick(object sender, EventArgs e)
    {
        Console.WriteLine("I tick!!");
    }
}
  

И код переназначения становится

 var foo = new MyClass();

//Do stuff....

foo = new MyClass(foo);
  

Но мне интересно, действительно ли ответственность за остановку старого таймера должна лежать на вновь созданном экземпляре MyClass . С логической точки зрения кажется, что фрагмент кода, который создал объект, а затем что-то с ним сделал, также должен отвечать за остановку таймера только что созданного объекта. Поэтому я мог бы быть склонен согласиться с вашим оригинальным решением.