当ViewModel不可见时如何正确处理DispatcherTimer /队列

在具有MVVM模式的WPF应用程序中,我有一个DockManager,它根据客户的配置显示不同的窗格。

其中一些View / ViewModel使用DispatcherTimer处理来自队列的数据,该数据在经过一段时间并处理队列之后(选择该选项是因为数据以很高的频率处理并且直接绑定到DataItems会降低性能。

做一些测试,我发现(这是正确的)即使没有显示View / ViewModel,DispacterTimer也会被调用,并且这占用了主线程上的资源,该资源最好执行其他操作,然后更新无用的ViewModel(因为数据已更新)频繁,因此当用户按顶部的窗格时,更新的数据有99%是旧的)

我想知道处理这些数据的最佳方法是什么。乍一看,我想完全跳过更新,然后将其委托给以后的过程(将视图推到顶部时,但是这样,在显示最新数据之前,我将需要做很多工作。

我的第一个想法是添加,if(!IsActive) return但这不会处理队列,有什么建议吗?


波斯汪
浏览 281回答 2
2回答

qq_遁去的一_1

这就是您的管理方式。。。您必须选择在何处处理数据并在ViewModel中进行转换。唯一的事情是在调度程序线程上填充可观察对象。主视图模型_UpdateTimerClock = new DispatcherTimer();_UpdateTimerClock.Interval = new TimeSpan(0, 0, 6);_UpdateTimerClock.IsEnabled = true;_UpdateTimerClock.Tick += UpdateTimerClockElapsed;public void UpdateTimerClockElapsed(object tag, EventArgs args){&nbsp; &nbsp; try&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Messenger.Default.Send(new NotificationViewModelRefresh());&nbsp; &nbsp; }&nbsp; &nbsp; catch (Exception err)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; BusinessLogger.Manage(err);&nbsp; &nbsp; }}子视图模型public ViewModel(){&nbsp; &nbsp; try&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Messenger.Default.Register<NotificationViewModelRefresh>(this, HandleRefreshAction);&nbsp; &nbsp; }&nbsp; &nbsp; catch (Exception error)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; BusinessLogger.Manage(error);&nbsp; &nbsp; }}private void HandleRefreshAction(NotificationViewModelRefresh msg){&nbsp; &nbsp; if (!this.IsVisible)&nbsp; &nbsp; &nbsp; &nbsp; return;儿童观public View(){&nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; if (!DesignerProperties.GetIsInDesignMode(this))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; this.IsVisibleChanged += (o, e) =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.IsVisible)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (this.DataContext as ViewModel).Refresh();&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }}在计时器中的刷新或更常规的处理任务中...Task tk = Task.Factory.StartNew(() =>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (System.Threading.Monitor.TryEnter(_RefreshLocker))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VisualHelper.InvokeBackground(() =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {视觉辅助提取物private static void BeginInvoke(DispatcherPriority prio, Action action)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Application.Current != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Application.Current.Dispatcher.CheckAccess())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Application.Current.Dispatcher.BeginInvoke(prio, (ThreadStart)(() => action()));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (Exception err)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BusinessLogger.Manage(err);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP