wake-up-neo.com

Wie wird ein Ereignis ausgelöst, wenn der Wert einer Variablen geändert wird?

Ich erstelle gerade eine Anwendung in C # mit Visual Studio. Ich möchte einen Code erstellen, damit, wenn eine Variable den Wert 1 hat, ein bestimmter Code ausgeführt wird. Ich weiß, dass ich eine if-Anweisung verwenden kann, aber das Problem ist, dass der Wert in einem asynchronen Prozess geändert wird, sodass die if-Anweisung technisch gesehen ignoriert werden kann, bevor sich der Wert geändert hat.

Ist es möglich, einen Ereignishandler zu erstellen, damit ein Ereignis ausgelöst wird, wenn sich der Variablenwert ändert? Wenn ja, wie kann ich das machen?

Es ist durchaus möglich, dass ich falsch verstanden habe, wie eine if-Anweisung funktioniert! Jede Hilfe wäre sehr dankbar.

89
James Mundy

Mir kommt es so vor, als ob Sie eine Immobilie anlegen möchten.

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

private int _myProperty;

Auf diese Weise können Sie bei jeder Änderung des Eigenschaftswerts Code ausführen. Sie könnten hier ein Ereignis auslösen, wenn Sie wollten.

112
Jonathan Wood

Sie können einen Eigenschaftssetter verwenden, um ein Ereignis auszulösen, wenn sich der Wert eines Felds ändert.

Sie können Ihren eigenen EventHandler-Delegaten haben oder den berühmten System.EventHandler-Delegaten verwenden.

Normalerweise gibt es ein Muster dafür:

  1. Definieren Sie ein öffentliches Ereignis mit einem Event-Handler-Delegaten (der ein Argument vom Typ EventArgs hat).
  2. Definieren Sie eine geschützte virtuelle Methode mit dem Namen OnXXXXX (z. B. OnMyPropertyValueChanged). Bei dieser Methode sollten Sie überprüfen, ob der Event-Handler-Delegat null ist, und wenn nicht, können Sie ihn aufrufen (dies bedeutet, dass eine oder mehrere Methoden an die Event-Delegation angehängt sind).
  3. Rufen Sie diese geschützte Methode auf, wenn Sie Abonnenten benachrichtigen möchten, dass sich etwas geändert hat.

Hier ist ein Beispiel

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

Der Vorteil dieses Ansatzes besteht darin, dass Sie anderen Klassen, die von Ihrer Klasse erben möchten, erlauben, das Verhalten bei Bedarf zu ändern.

Wenn Sie ein Ereignis in einem anderen Thread abfangen möchten, der gerade ausgelöst wird, müssen Sie darauf achten, den Status von Objekten, die in einem anderen Thread definiert sind, nicht zu ändern, wodurch eine Kreuzthread-Ausnahme ausgelöst wird. Um dies zu vermeiden, können Sie entweder eine Invoke-Methode für das Objekt verwenden, dessen Status Sie ändern möchten, um sicherzustellen, dass die Änderung in demselben Thread erfolgt, in dem das Ereignis ausgelöst wurde, oder für den Fall, dass Sie sich mit einem Windows Form beschäftigen Mit einem BackgourndWorker können Dinge in einem parallelen Thread erledigt werden. Schön und einfach.

58
Beatles1692

Das .NET Framework bietet tatsächlich eine Schnittstelle, über die Sie Abonnenten benachrichtigen können, wenn sich eine Eigenschaft geändert hat: System.ComponentModel.INotifyPropertyChanged. Diese Schnittstelle verfügt über ein PropertyChanged-Ereignis. Es wird normalerweise in WPF zum Binden verwendet, aber ich habe es als eine Möglichkeit zur Standardisierung der Benachrichtigung über Eigenschaftsänderungen in Geschäftsschichten als nützlich erachtet.

In Bezug auf die Fadensicherheit würde ich ein Schloss im Setter unterbringen, damit Sie keinen Rennbedingungen ausgesetzt sind.

Hier sind meine Gedanken in Code :):

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

Hoffe das ist hilfreich :)

43
Daniel Sandberg

benutze einfach eine Eigenschaft

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