0

I need to update an SQLite database when a class property changes. Here is a poor implementation that demonstrates exactly what needs to be accomplished on a larger scale:

internal class MyClass
{
    private bool isFoo;

    internal bool IsFoo
    {
        get { return isFoo; }

        private set
        {
            isFoo = value;
            UpdateDatabase(); // ← This method could take some time.
        }
    }

    private void UpdateDatabase()
    {
        DatabaseClass.Update(this);
    }
}

SO user, LukeH, said in an answer:

if two threads access [a property] simultaneously, the getter will briefly block the second thread until it returns the object to the first thread...

Current Direction

I don't want to block access to the property. If I implement INotifyPropertyChanged, my code will either be inconsistent in how it saves data or turn DatabaseClass into a mess of handlers. Here is the approach that I am reluctant to use:

public class MyClass
{
    private bool isFoo;

    internal bool IsFoo
    {
        get { return isFoo; }

        private set
        {
            isFoo = value;
            UpdateRequesting(); // Call delegate, similar to INotifyPropertyChanged
        }
    }

    // Private event and delegate.
    private delegate bool OnUpdateRequesting();
    private event OnUpdateRequesting UpdateRequesting;

    internal MyClass()
    {
        // Subscribe to private event inside of constructor.
        UpdateRequesting += UpdateDatabase;
    }

    // Now, raised by event rather than called directly from set accessor.
    private bool UpdateDatabase()
    {
        return DatabaseClass.Update(this);
    }
}

Using private events feels like I'm dialing my own phone number. What is the correct way to get UpdateDatabase() called without locking properties?

Community
  • 1
  • 1
Tyler Pantuso
  • 835
  • 8
  • 16
  • When `IsFoo` change, you build a Sql command from it, in UI thread, then you can execute at other thread. that way you can implement `INotifyPropertyChanged` with no problem – NoName Feb 27 '16 at 09:35
  • @Sakura : Implementing `INotifyPropertyChanged` would be nearly identical to the code above. Just replace `OnUpdateRequesting` with `OnPropertyChanged`; however, it would require unnecessary instances of `MyClass` and `PropertyChangedEventArgs`. – Tyler Pantuso Feb 27 '16 at 10:06
  • How you use `UpdateRequesting();`? Did you call a function to refresh the UI, or you set value to a control? – NoName Feb 27 '16 at 10:09
  • @Sakura : `get { } set { UpdateRequesting() }` – Tyler Pantuso Feb 27 '16 at 20:25
  • @Sakura : Typically, the properties get set when the end user clicks a button, or changes a setting. – Tyler Pantuso Feb 27 '16 at 20:35

1 Answers1

0

Simply add IsAsync = True to your Binding, and your first approach would work.

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38