基于WPF的Dispatcher应用及探讨(三)
来源:互联网 发布:公安大数据应用与问题 编辑:程序博客网 时间:2024/06/06 02:42
现在我们在搭建好的MVVM架构中实现Dispatcher:
我们把之前作成的CustomizeDispatcher放入PresenterBase中调用,
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Input;using System.Threading.Tasks;using System.Windows.Threading;namespace HarlyApp.BaseFiles{ public class PresenterBase<T> { public IView<T> view { get; set; } private ICommand _cancelCommand; public ICommand CancelCommand { get { if (_cancelCommand == null) { _cancelCommand = new RelayCommand(() => this.CloseWindow()); } return _cancelCommand; } } public PresenterBase(IView<T> view) { this.view = view; this.Initialize(); } public void ShowDialog() { this.view.ShowWindow(); } protected virtual void Initialize() { } public void CloseWindow() { this.view.CloseWindow(); } public List<Exception> exceptionList = new List<Exception>(); public bool CustomizeDispatcher(Action<bool> callbackAction, params Action[] actions) { Func<bool> function = new Func<bool> (() => { ParallelLoopResult result = Parallel.For(0, actions.Length, (int ac, ParallelLoopState state) => { try { actions[ac].Invoke(); } catch (Exception ex) { exceptionList.Add(ex); } }); return !exceptionList.Any(); }); callbackAction.Invoke(function.Invoke()); return !exceptionList.Any(); } }}
后台我这边用了最简单的entityFramework并写了个get方法进行调用,
我们用Classes,Components,GamePlans这3个集合作为Itemsource进行绑定
using System;using System.Collections.Generic;using System.Linq;using System.Text;using HarlyApp.BaseFiles;using System.Windows.Input;using System.Windows;using DataBaseEntity;using System.Collections.ObjectModel;namespace HarlyApp{ public class MainWindowPresenter : PresenterBase<MainWindow> { public DataRepository dataaccess = new DataRepository(); private ICommand _displayCommand; public ICommand DisplayCommand { get { if (_displayCommand == null) { _displayCommand = new RelayCommand(() => this.Display()); } return _displayCommand; } } public ObservableCollection<ACL_CLASS> Classes { get; set; } public ObservableCollection<SR_COMPONENT> Components { get; set; } public ObservableCollection<SR_GAMEPLAN> GamePlans { get; set; } public MainWindowPresenter(IView<MainWindow> view) : base(view) { this.view.DataContext = this; } StringBuilder sb = new StringBuilder(); protected override void Initialize() { this.Classes = new ObservableCollection<ACL_CLASS>(); this.Components = new ObservableCollection<SR_COMPONENT>(); this.GamePlans = new ObservableCollection<SR_GAMEPLAN>(); } public void Display() { this.CustomizeDispatcher( complete => { if (complete) MessageBox.Show("Complete"); else MessageBox.Show("Failed"); }, () => { this.dataaccess.GetItems<ACL_CLASS>().ToList().ForEach(c=>this.Classes.Add(c)); }, () => { this.dataaccess.GetItems<SR_COMPONENT>().ToList().ForEach(c=>this.Components.Add(c)); }, () => { this.dataaccess.GetItems<SR_GAMEPLAN>().ToList().ForEach(c=>this.GamePlans.Add(c)); }); } }}
看似很正常的source,但是跑的结果确实Failed,看了下结果其实是ObserverableCollection集合的问题,这个集合不支持异步调用以及集合修改,这个问题网上有好多了,直接把解决方法贴在下面:
using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Collections.Specialized;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading;namespace HarlyApp.BaseFiles{ public class AsyncObservableCollection<T> : ObservableCollection<T> { //获取当前线程的SynchronizationContext对象 private SynchronizationContext _synchronizationContext = SynchronizationContext.Current; public AsyncObservableCollection() { } public AsyncObservableCollection(IEnumerable<T> list) : base(list) { } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (SynchronizationContext.Current == _synchronizationContext) { //如果操作发生在同一个线程中,不需要进行跨线程执行 RaiseCollectionChanged(e); } else { //如果不是发生在同一个线程中 //准确说来,这里是在一个非UI线程中,需要进行UI的更新所进行的操作 _synchronizationContext.Post(RaiseCollectionChanged, e); } } private void RaiseCollectionChanged(object param) { // 执行 base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { if (SynchronizationContext.Current == _synchronizationContext) { // Execute the PropertyChanged event on the current thread RaisePropertyChanged(e); } else { // Post the PropertyChanged event on the creator thread _synchronizationContext.Post(RaisePropertyChanged, e); } } private void RaisePropertyChanged(object param) { // We are in the creator thread, call the base implementation directly base.OnPropertyChanged((PropertyChangedEventArgs)param); } }}
我们把ObservarableCollection集合换成AsyncObservableCollection后,结果是出来了,初步设想得到了实现,不过还需要进行进一步测试以及优化,我们会在下一节来看看结果。
0 0
- 基于WPF的Dispatcher应用及探讨(三)
- 基于WPF的Dispatcher应用及探讨(一)
- 基于WPF的Dispatcher应用及探讨(二)
- 基于WPF的Dispatcher应用及探讨(四)
- 基于Cocoon的应用(二)及系统权限探讨
- 基于Cocoon的应用(二)及系统权限探讨
- 深入WPF -- Dispatcher(补)
- 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分)
- 基于J2EE的MVC设计模式的WEB应用开发应用及探讨
- WPF- Dispatcher
- WPF-Dispatcher
- 探讨Java之桌面应用的可行性(三)
- 通过实例理解WPF的Dispatcher
- Linux的应用--Video Streaming探讨 三
- WPF中的模板(三)- ControlTemplate和DataTemplate的应用
- [探讨]分布式文件系统的应用及选择
- 基于MFC的五子棋应用(三)
- WPF multi-thread - Dispatcher WPF多线程 - Dispatcher
- C语言中的联合体和结构体
- Clojure Github 项目收藏
- 【转】5分钟使用Visual Studio和SVN建立源代码管理
- 什么是I帧,P帧,B帧
- nohup
- 基于WPF的Dispatcher应用及探讨(三)
- Source Insight 3.5快捷键大全
- 【Android增量升级系列_02】 浅谈Android增量更新服务端的实现方法
- 文件下载
- 建造者模式
- 创建seam文件
- 【算法导论】幻方算法
- 单例模式
- eclipse的注释字体大小如何修改?