【问题标题】:The calling thread cannot access this object because a different thread owns it - BackgroundWorker error [duplicate]调用线程无法访问此对象,因为不同的线程拥有它 - BackgroundWorker 错误 [重复]
【发布时间】:2014-12-25 10:25:01
【问题描述】:

我有下面的代码示例。我想使用 BackGroundWorker,但出现错误。

让我解释一下代码;

  • GridData 属性是视图上 DataGrid 的来源。
  • 我有一个将 Excel 数据保存到 db 的按钮,它与 SaveExcel:ICommand 类绑定。
  • 当我按下此按钮时,它会在视图模型中调用 SaveExcel 方法。
  • 在保存 excel 后的 SaveExcel 方法中,我想刷新网格数据,所以我用数据表设置了 GridData 属性。
  • 当我设置这个属性时,PropertyChanged 事件被调用,该事件在 SaveGrid:ICommand 类中被委托。(这个类与另一个按钮绑定)
  • 在这里,CanExecuteChanged 方法给我错误,“调用线程无法访问此对象,因为不同的线程拥有它”。

我该如何解决这个问题?

任何帮助表示赞赏。

            public class MainViewModel
            {
                public DataTable GridData{get;set;}

                public void SaveExcel()
                {
                    .
                    .
                    .
                    RefreshGridData();
                }

                public void RefreshGridData()
                {
                    .
                    .
                    .
                    GridData = <selectedGridData>;
                }

                private void bgw_DoWork(object sender, DoWorkEventArgs e)
                {
                    SaveExcel();
                }
            }


            public class SaveExcel : ICommand
            {
                private MainViewModel viewModel;
                public SaveExcel(MainViewModel viewModel)
                {
                    this.viewModel = viewModel;
                    viewModel.PropertyChanged += (s, e) =>
                    {
                        if (CanExecuteChanged != null &&
                            (e.PropertyName == "SelectedA" || e.PropertyName == "SelectedB"))
                        {
                            CanExecuteChanged(this, new EventArgs());
                        }
                    };
                }

                public bool CanExecute(object parameter)
                {
                    return (viewModel.SelectedA != null && viewModel.SelectedB != null);
                }

                public event EventHandler CanExecuteChanged;

                public void Execute(object parameter)
                {
                    viewModel.bgw.RunWorkerAsync();
                }
            }


            public class SaveGrid : ICommand
            {
                private MainViewModel viewModel;
                public SaveGrid(MainViewModel viewModel)
                { 
                    this.viewModel = viewModel;
                    viewModel.PropertyChanged += (s, e) =>
                    {
                        if (CanExecuteChanged != null && e.PropertyName == "GridData")
                        {
                            CanExecuteChanged(this, new EventArgs());
                        }
                    };
                }

                public bool CanExecute(object parameter)
                {
                    return (viewModel.GridData.Rows.Count > 0);
                }

                public event EventHandler CanExecuteChanged;

                .
                .
                .
                .

            }

【问题讨论】:

    标签: c# wpf multithreading mvvm backgroundworker


    【解决方案1】:

    您需要在 UI 线程上调用刷新,在 WPF 中,您可以通过在代码中的适当位置调用 Dispatcher.Invoke 来执行此操作。例如

    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => RefreshGridData()));
    

    【讨论】:

    • 谢谢 Ned,你把我从一个非常大的问题中解救了出来。
    • 没问题@baris usanmaz,我很高兴我能提供帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多