Как вызвать событие при изменении значения переменной?

в настоящее время я создаю приложение на C# с помощью Visual Studio. Я хочу создать некоторый код, чтобы, когда переменная имеет значение 1, выполнялся определенный фрагмент кода. Я знаю, что могу использовать оператор if, но проблема в том, что значение будет изменено в асинхронном процессе, поэтому технически оператор if может быть проигнорирован до изменения значения.

можно ли создать обработчик событий, чтобы при изменении значения переменной событие сработало? Если да, то как я могу это сделать?

вполне возможно, что я мог неправильно понять, как работает оператор if! Любая помощь будет высоко ценится.

4 ответов


Мне кажется, что вы хотите создать свойство.

public int MyProperty
{
    get { return _myProperty; }
    set
    {
        _myProperty = value;
        if (_myProperty == 1)
        {
            // DO SOMETHING HERE
        }
    }
}

private int _myProperty;

Это позволяет запускать некоторый код при каждом изменении значения свойства. Вы можете устроить здесь мероприятие, если хотите.


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

вы можете иметь свой собственный делегат EventHandler или использовать известную систему.Делегат EventHandler в.

обычно для этого есть шаблон:

  1. определите публичное событие с делегатом обработчика событий (который имеет аргумент типа EventArgs).
  2. определите защищенный виртуальный метод, называемый OnXXXXX (OnMyPropertyValueChanged для образец.) В этом методе вы должны проверить, является ли делегат обработчика событий нулевым, а если нет, вы можете его вызвать (это означает, что к делегированию событий прикреплен один или несколько методов).
  3. вызовите этот защищенный метод всякий раз, когда вы хотите уведомить подписчиков, что что-то изменилось.

вот пример

private int _age;

//#1
public event System.EventHandler AgeChanged;

//#2
protected virtual void OnAgeChanged()
{ 
     if (AgeChanged != null) AgeChanged(this,EventArgs.Empty); 
}

public int Age
{
    get
    {
         return _age;
    }

    set
    {
         //#3
         _age=value;
         OnAgeChanged();
    }
 }

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

Если вы хотите поймать событие в другом потоке, которое оно вызывается, вы должны быть осторожны, чтобы не изменить состояние объектов, определенных в другом потоке, которое вызовет исключение перекрестного потока. Чтобы избежать этого, можно использовать метод Invoke для объекта, состояние которого необходимо изменить, чтобы убедиться, что изменение происходит в том же потоке, что событие было вызвано, или в случае, если вы имеете дело с Windows Form можно используйте BackgourndWorker, чтобы делать вещи в параллельном потоке красиво и легко.


.NET framework фактически предоставляет интерфейс, который можно использовать для уведомления подписчиков при изменении свойства: System.ComponentModel.INotifyPropertyChanged в. Этот интерфейс имеет одно событие PropertyChanged. Его обычно используют в WPF для привязки, но я нашел его полезным в бизнес-слоях как способ стандартизации уведомления об изменении свойств.

С точки зрения безопасности потоков я бы поставил блокировку в сеттере, чтобы вы не столкнулись с какой-либо гонкой условия.

вот мои мысли в код :) :

public class MyClass : INotifyPropertyChanged
{
    private object _lock;

    public int MyProperty
    {
        get
        {
            return _myProperty;
        }
        set
        {
            lock(_lock)
            {
                //The property changed event will get fired whenever
                //the value changes. The subscriber will do work if the value is
                //1. This way you can keep your business logic outside of the setter
                if(value != _myProperty)
                {
                    _myProperty = value;
                    NotifyPropertyChanged("MyProperty");
                }
            }
        }
    }

    private NotifyPropertyChanged(string propertyName)
    {
        //Raise PropertyChanged event
    }
    public event PropertyChangedEventHandler PropertyChanged;
}


public class MySubscriber
{
    private MyClass _myClass;        

    void PropertyChangedInMyClass(object sender, PropertyChangedEventArgs e)
    {
        switch(e.PropertyName)
        {
            case "MyProperty":
                DoWorkOnMyProperty(_myClass.MyProperty);
                break;
        }
    }

    void DoWorkOnMyProperty(int newValue)
    {
        if(newValue == 1)
        {
             //DO WORK HERE
        }
    }
}

надеюсь, это полезно:)


просто используйте свойство

int  _theVariable;
public int TheVariable{
  get{return _theVariable;}
  set{
    _theVariable = value; 
    if ( _theVariable == 1){
      //Do stuff here.
    }
  }
}