Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Обычно существует шаблон для этого:

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

Здесь пример

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, чтобы сделать что-то в параллельном потоке красивым и легким.

Ответ 3

Структура .NET фактически предоставляет интерфейс, который вы можете использовать для уведомления подписчиков при изменении свойства: 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
        }
    }
}

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

Ответ 4

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

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