WPF MVVM System.Threading.Timer in Model. How does View get notified?

I have a project where I want to use a System.Threading.Timer in the Model to make it "go".

I figure the Model should run by itself and not be concerned about the View. So I don't want to use DispatchTimer in the Model.

It sounds nice to have a Model that can utilize true parallelism. There's a lot of computation to be done, and the computer has a lot of CPU cores.

It looks like a PITA to deal with locking variables when updating them so everything is thread safe, but the effort may be worth it if the result runs significantly faster.

I'm wondering though, how will notifying the View of updates work? Will it work at all if the NotifyPropertyChanged() is initiated from the Model via the System.Threading.Timer Tick event?

Eventually somehow the ViewModel needs to notify the View that a display variable has been updated, and the View needs to be running on the UI thread, which I assume is the DispatchThread.

In WinForms we'd do this by testing with InvokeRequired and then calling BeginInvoke if we're not on the UI thread.

What is the equivalent for WPF using the MVVM paradigm? Where does it make the jump to the UI thread?

I envision the Model having a Property which gets updated by System.Threading.Timer, and the Property calls NotifyPropertyChanged(), and the ViewModel subscribes to this event, so the VIewModel event handler is being called from the Model's  System.Threading.Timer Tick event handler, on whatever thread that's on. The ViewModel has it's own corresponding Property for the View to look at. The ViewModel property's getter just fetches the value from the Model. The ViewModel's PropertyChangedEventHandler just calls it's own NotifyPropertyChanged() to notify the VIew.

Let me write some sample code here of what I'm thinking (the following isn't complete, it's just a sketch):
    class Model
    {
        private int myInt;
        public int MyInt
        {
            get
            {
                return myInt;
            }
            set
            {
                if (myInt != value)
                {
                    myInt = value;
                    NotifyPropertyChanged();
                }
            }
        }

        var timer = new System.Threading.Timer();
        public Model()
        {
           set up timer...
        }
        private void TimerTIck()
        {
                update MyInt using locks
        }
    }

    class MainWindowViewModel
    {
        private Model model;

        public string MyIntText
        {
            get
            {
                return model.myInt.ToString;
            }
            set
            {
                if (myIntText != value)
                {
                    myIntText = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private void ModelPropertyChangedEventHandler(object sender, PropertyChangedEventArgs e)
        {
            switch(e.PropertyName)
            {
                case nameof(model.MyInt):
                    NotifyPropertyChanged("MyIntText");
                    break;
            }
        }

        public MainWindowViewModel()
        {
            this.model = new Model();
            this.DataContext = model;
        }
    }

Open in new window

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox Text="{Binding MyIntText}" />
    </Grid>
</Window>

Open in new window

I'm starting to worry about what happens when the Model is driven by  System.Threading.Timer. Somewhere along the line the PropertyChanged event needs to jump to the UI thread, and I don't see that happening anywhere.

What's missing?

(I'm also a bit wary of the case statement that jumps from MyInt to MyIntText.)

(I saw an example of System.Threading.Timer that made it look quite complicated to use:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/threading/thread-timers#thread-timer-example)
deleydSoftware EngineerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Wayne BradneyIndependent ConsultantCommented:
WPF uses databinding, whereby the View and the ViewModel are bound together via the INotifyPropertyChanged.OnPropertyChanged event. In this case the binding subsystem will automatically subscribe to the event and marshal updates to the dispatcher thread.

It looks like in your case you could probably collapse your Model and ViewModel into a single ViewModel which performs the asynchronous updates.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
WPF

From novice to tech pro — start learning today.