Search code examples
mvvmtimeruwp.net-coreprism

DispatcherTimer in MVVM with Prism?


I'm working on a multi-platform MVVM app, and I want to keep the ViewModel platform-agnostic.

I need to make use of DispatcherTimer or any other timer. Since the DispatcherTimer is not part of .NET Standard/Core, I was wondering if there are better alternatives to use so I can keep the VM clean of plat-specific code (I want it to depend only on .NET Core)?

The way it works is that the ViewModel implements an interface that exposes an event that the View is listening to, and responds to it accordingly.
The timer raises this event upon each tick.


Solution

  • The first option would be to just use classic Timer, which does fire on a non-UI thread and then just use Dispatcher manually in the consuming view. This is however not that convenient.

    Other option would be to provide an interface, that consumers of your library could implement, which would have a method like RunOnUiThread(Action action) and which you would just use to make sure the view-specific code runs on the UI thread.

    The best solution would probably be to get inspiration in Prism itself. For example the EventAggregator in the library can publish events on the UI thread - it first captures the current thread's synchronization context (see here on GitHub):

    var syncContext = SynchronizationContext.Current;
    

    This must be done for example during the View model construction, on the UI thread. And then you can invoke an action on this UI synchronization context even from another thread (see here on GitHub):

    syncContext.Post((o) => action(), null);
    

    This way you could just use one of the .NET Standard Timer classes and from their callback then use the SynchronizationContext to run an action on UI thread.