我正在开发一个多平台MVVM应用程序,并且希望保持ViewModel平台不可知。
我需要使用DispatcherTimer
或任何其他计时器。由于DispatcherTimer
不是.NET Standard / Core的一部分,我想知道是否还有更好的替代方法可以使用,以便使VM不受平台特定代码的影响(我希望它仅取决于.NET Core。 )?
它的工作方式是ViewModel实现一个接口,该接口公开View正在监听的事件,并相应地对其做出响应。
计时器在每个刻度上引发此事件。
答案 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将在主线程中运行,我认为您 可以考虑在框架中使用此方法。