基于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
原创粉丝点击