从后面的代码访问viewmodel属性集的交叉线程异常

时间:2015-08-27 22:41:11

标签: wpf multithreading mvvm thread-safety

我有一个WPF MVVM应用程序,它在telerik网格视图中显示药物信息。我想在视图模型中进行一些过滤和分页,但我一直在获得跨线程异常。初始负载工作正常。我可以毫无问题地更改页面/页面大小。当我过滤网格时,我在后面的代码中创建一个IEnumerable的FilterDescriptors,然后在视图模型的Filters属性上设置它。此时,我在使用过滤器进行查询时遇到了跨线程异常。我已经尝试了我能想到的一切,但无法让它发挥作用。

 public partial class DrugEdit : Page
    {
        public DrugEdit()
        {
            InitializeComponent();
        }

        private void RadGridView1_Filtered(object sender, Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs e)
        {

            DrugEditViewModel vm = this.DataContext as DrugEditViewModel;
            Telerik.Windows.Controls.RadGridView gv = sender as Telerik.Windows.Controls.RadGridView;

            if (gv.FilterDescriptors == null || gv.FilterDescriptors.Count == 0)
                vm.Filters = null;
            else
            {
                List<FilterDescriptor> filters = (vm.Filters==null? new List<FilterDescriptor>(): vm.Filters.ToList());

                foreach (FilterDescriptor  r in e.Removed)
                {
                    var fnd = filters.FirstOrDefault(x => x.Member == r.Member);
                    if (fnd == null) continue;
                    filters.Remove(fnd);
                }

                foreach (FilterDescriptor a in e.Added)
                {
                    var fnd = filters.FirstOrDefault(x => x.Member == a.Member);
                    if (fnd == null)
                    {
                        filters.Add(new FilterDescriptor(a.Member, a.Operator, a.Value, false, a.MemberType));
                    }
                    else
                    {
                        fnd.Operator = a.Operator;
                        fnd.Value = a.Value;
                    }
                }
                vm.Filters = filters;
            }

        }
    }




  public class DrugEditViewModel
        : ViewModelBase
    {

        private Data.DBContext ctx = new Data.DBContext();


        private List<FilterDescriptor> FiltersValue = new List<FilterDescriptor>();
        public List<FilterDescriptor> Filters
        {
            get { return FiltersValue; }
            set
            {
                SetPropertyValue((() => Filters), ref FiltersValue, value);
                RecordCount = 0;
                LoadData();
            }
        }

        private int PageValue = 0;
        public int Page
        {
            get { return PageValue; }
            set
            {
                SetPropertyValue((() => Page), ref PageValue, value);
                LoadData();
            }
        }

        private int PageSizeValue = 20;
        public int PageSize
        {
            get { return PageSizeValue; }
            set
            {
                SetPropertyValue((() => PageSize), ref PageSizeValue, value);
                Page = 0;
            }
        }

        private int RecordCountValue;
        public int RecordCount
        {
            get { return RecordCountValue; }
            set
            {
                SetPropertyValue((() => RecordCount), ref RecordCountValue, value);
            }
        }

        private ObservableCollection<Models.Drug> DrugsValue;
        public ObservableCollection<Models.Drug> Drugs
        {
            get { return DrugsValue; }
            set
            {
                SetPropertyValue((() => Drugs), ref DrugsValue, value);
            }
        }

        #endregion

        #region Methods


          private void LoadData()
        {
            if (ctx == null)
                ctx = new Data.DBContext();

            //load record count if we don't have it.
            if (RecordCount == 0)
            {
                IsBusy = true;
                Task.Run(() =>
                {
                    if (Filters == null || Filters.Count() == 0)
                    {
                        RecordCount = ctx.Set<Entities.Drug>().Count();
                    }
                    else
                    {
                        RecordCount = ctx.Set<Entities.Drug>().Where(Filters).Count();
                    }
                    IsBusy = false;
                    LoadData();
                });
                return;
            }

            IsBusy = true;
            Task.Run(() =>
            {

                if (Filters == null || Filters.Count() == 0)
                    currentPage = (from d in ctx.Query<Entities.Drug>()
                                   orderby d.NDC
                                   select d)
                               .Skip(PageSize * Page)
                               .Take(PageSize).ToList();
                else
                    currentPage = (from d in ctx.Query<Entities.Drug>()
                                   orderby d.NDC
                                   select d)
                                   .Where(Filters)
                                   .Skip(PageSize * Page)
                                   .Take(PageSize)
                                   .ToIList() as List<Entities.Drug>;

                Drugs = new ObservableCollection<Models.Drug>((from c in currentPage
                                                               select new Models.Drug(c)));

                IsBusy = false;
            });

        }

        #endregion
    }

0 个答案:

没有答案