-1

Here is the scenario, I have about 50 globals, a UDP listener(which works in it's own thread) changes them when it receives new package.

Another thread(other than the main) periodically(24 times a second) reads all of those vars, and changes some UI elements.

As you might imagine, that's a pretty ungainly way of doing it. Also, I'm pretty sure, sometimes I'm having race conditions. So it's not threadsafe either.

So I decided to use events attached to properties that would fire as soon as there is a change. After some search I found this:

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

Which i got from "Daniel Sandberg". I'm pretty sure this code would do what I want. Thing is, applying that code for 50 properties don't feel like proper OOP.Shouldn't there be a easier way to raise events?

Back in the ActionScript days, this kind of event could be raised with a single line of code. C#'s event system never made much sense to me....

Community
  • 1
  • 1
flanker
  • 101
  • 6
  • You can use some AOP (Aspect Oriented Programming) framework for C#, for example PostSharp (free version should be enough to do what you need I think). There you can define an aspect and apply it to all properties of a class with the single line of code, just like you want. – Evk Nov 14 '16 at 05:54
  • Well, once you've got 50 global properties - especially that are constantly being read and written - you're already well out of the bounds of OOP anyway. AOP as Evk mentioned is one way. You could also delegate the event dispatching to your UDP listener and write it generically. Or you can generate the class (either via IL or a templating engine). – Rob Nov 14 '16 at 06:04
  • @Rob I know using globals extensively is frowned upon. A bad habit from working with microcontrollers. Thought about using UDP listener to create new threads to process each received package. But I don't think that'd be smart considering i can't control how often new packages arrive. Unless implemented very carefully, it'd cause race conditions. Never heard of AOP before. Sounds interesting. I'll check it. – flanker Nov 14 '16 at 06:09
  • 1
    There's nothing in your question that explains what threads have to do with this. As far as implementing `INotifyPropertyChanged`, see the marked duplicate, as well as questions like https://stackoverflow.com/questions/3130491/how-to-avoid-implementing-inotifypropertychanged-manually and https://stackoverflow.com/questions/7063902/better-way-to-trigger-onpropertychanged (both of which include mention of Postsharp and other AOP approaches). – Peter Duniho Nov 14 '16 at 07:20

1 Answers1

0

Nothing is wrong with raising the property changed event for each property. That is still in-line with OOP.

For better code management, I suggest using T4 Text Template. If you are unfamiliar with this, it is microsoft's text template which allows you to program a template for your code.

In my previous work, we utilized this together with the MVVMCross Framework. The goal is to just add the property name in your template and it should automatically create all the basic necessary stuff for you. Also, text templates are often used for partial class so you can just add the other necessary code in a separate file as the code generated by the text templates are absolute. Manual modifications on the generated file are overridden whenever code build occurs.

Note: The learning curve is a bit steep but it will really help you maintain cleaner code.

jegtugado
  • 4,701
  • 1
  • 8
  • 32