带有棱镜的MVVM中的DispatcherTimer?

时间:2018-11-01 14:39:51

标签: mvvm timer uwp .net-core prism

我正在开发一个多平台MVVM应用程序,并且希望保持ViewModel平台不可知。

我需要使用DispatcherTimer或任何其他计时器。由于DispatcherTimer不是.NET Standard / Core的一部分,我想知道是否还有更好的替代方法可以使用,以便使VM不受平台特定代码的影响(我希望它仅取决于.NET Core。 )?

它的工作方式是ViewModel实现一个接口,该接口公开View正在监听的事件,并相应地对其做出响应。
计时器在每个刻度上引发此事件。

2 个答案:

答案 0 :(得分:1)

第一种选择是只使用经典的Timer,它会在非UI线程上触发,然后在使用视图中手动使用Dispatcher。但是,这并不方便。

其他选择是提供一个接口,库的使用者可以实现该接口,该接口具有类似RunOnUiThread(Action action)的方法,并且您将使用该接口来确保特定于视图的代码在UI线程上运行

最好的解决方案可能是从Prism本身获得灵感。例如,库中的EventAggregator可以在UI线程上发布事件-它首先捕获当前线程的同步上下文(请参见here on GitHub):

var syncContext = SynchronizationContext.Current;

例如,必须在UI线程上的View模型构建期间完成此操作。然后,您甚至可以从另一个线程在此UI同步上下文上调用操作(请参见here on GitHub):

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

这样,您可以只使用.NET标准Timer classes之一,并从其回调中使用SynchronizationContext在UI线程上运行操作。

答案 1 :(得分:1)

您应该了解DispatcherTimer的另一种方式是,有时我们可能会使用DispatcherTimer交替执行某些操作。

有时我们可以使用Task.Delay来代替DispatcherTimer。

例如,我们需要每5秒运行一次代码A。

   public async void Foo()
    {
        while (true)
        {
            // run a every 5 seconds
            await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(5));
            A();
        }
    }

    private void A()
    {

    }

如果主线程调用Foo,那么A将在主线程中运行,我认为您  可以考虑在框架中使用此方法。