Soru Bir değişkenin değeri değiştirildiğinde olay nasıl tetiklenir?


Şu anda Visual Studio'yu kullanarak C # uygulamasında bir uygulama oluşturuyorum. Bir kod oluşturmak istiyorum, böylece bir değişkenin değeri 1 olduğunda belirli bir kod parçası gerçekleştirilir. Eğer bir if ifadesini kullanabileceğimi biliyorum ama problem, asenkronize bir süreçte değerin değişmesidir, bu yüzden eğer teknik, eğer değer değişmeden önce if ifadesi yok sayılabilirdi.

Bir olay işleyici oluşturmak mümkün mü, değişken değer değiştiğinde bir olay tetiklenir mi? Eğer öyleyse, bunu nasıl yapabilirim?

Bir if ifadesinin nasıl çalıştığını yanlış anlayabilmem mümkün! Herhangi bir yardım çok takdir edilecektir.


76
2018-04-30 14:21


Menşei


Sadece açık olmak gerekirse, bir değişkenin değişimini gözlemlemek, yalnızca sahip olduğunuz bir değişken için (veya zaten IObservable / INotifyPropertyChanged / Event ile ilgili) mümkündür. Gözlemlenmek üzere tasarlanmamışsa, bir sistem değişkeni değişimini gözlemleyemezsiniz. - Cœur


Cevaplar:


Bir mülk yaratmak istediğin gibi.

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

private int _myProperty;

Bu, özellik değeri her değiştiğinde bir kod çalıştırmanıza izin verir. Eğer istersen burada bir etkinlik düzenleyebilirsin.


95
2018-04-30 14:25





Bir alanın değeri her değiştiğinde bir etkinliği yükseltmek için bir özellik belirleyici kullanabilirsiniz.

Kendi EventHandler temsilcisine sahip olabilirsiniz veya ünlü System.EventHandler temsilcisini kullanabilirsiniz.

Genellikle bunun için bir model var:

  1. Bir olay işleyicisi temsilcisiyle (EventArgs türünde bir argümanı olan) bir genel olay tanımlayın.
  2. OnXXXXX (örneğin, OnMyPropertyValueChanged) adlı korumalı bir sanal yöntemi tanımlayın. Bu yöntemde, olay işleyicisinin temsilcisinin boş olup olmadığını kontrol etmeli ve eğer arama yapamıyorsanız (olay temsilcisine eklenmiş bir veya daha fazla yöntem var demektir).
  3. Abonelerin bir şeyin değiştiğini bildirmek istediğinizde bu korumalı yöntemi çağırın.

İşte bir örnek

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

Bu yaklaşımın avantajı, eğer gerekirse sınıfınızı devralmak isteyen diğer sınıfların davranışları değiştirmesine izin vermenizdir.

Farklı bir iş parçacığında bir olayın yakalanmasını istiyorsanız, başka bir iş parçacığında tanımlı nesnelerin durumunu değiştirmemeye dikkat etmelisiniz ki bu da çapraz iş parçacığı istisnasına neden olacaktır. Bundan kaçınmak için, durumu değiştirmek istediğiniz nesnedeki bir Invoke yöntemini kullanarak, olayın yükseltildiği aynı iş parçacığında değişiklik yapıldığından veya bir Windows Form'u ile uğraşmanızın gerekmediğinden emin olabilirsiniz. Paralel bir iş parçasında güzel ve kolay bir şeyler yapmak için bir BackgourndWorker kullanabilirsiniz.


47
2018-04-30 15:00



Tüm Web'deki en iyi açıklamalardan biri. Sonunda Özel Etkinlik İşleme'yi anladığımı düşünüyorum. Bu yazı için teşekkür ederiz. - Ricardo Garcia


.NET framework aslında bir özellik değiştiğinde abone bildirmek için kullanabileceğiniz bir arabirim sağlar: System.ComponentModel.INotifyPropertyChanged. Bu arayüzde bir özellik PropertyChanged var. WPF'de genellikle ciltleme için kullanılır, ancak işletme değişikliğinde, özellik değişikliği bildirimini standartlaştırmanın bir yolu olarak faydalı buldum.

İplik güvenliği açısından, herhangi bir yarış koşuluna girmemeniz için sette bir kilit koyardım.

İşte koddaki düşüncelerim :):

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

Umarım bu yardımcı olur :)


35
2018-04-30 21:13



Diğer cevapların gözardı edildiği kilitleme için +1. - ctacke
_Lock nesnesinin kullanımı nedir? - Lode Vlaeminck
@LodeVlaeminck, etkinlik işlenirken mülkün değerini değiştirmeyi önler. - David Suarez


sadece bir mülk kullan

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

8
2018-04-30 14:28