C# 如何使用WPF中的任务正确刷新网格中的数据

C# 如何使用WPF中的任务正确刷新网格中的数据,c#,wpf,data-binding,devexpress,task,C#,Wpf,Data Binding,Devexpress,Task,我的小WPF代码给了我这个错误 调用线程无法访问此对象,因为另一个线程拥有它 我知道它到底在说什么,但我无法理解如何修复它。我尝试过不同的事情,但没有运气,我承认我不擅长任务库 这就是我想要达到的目标 加载WPF表单时加载数据-这是正常的 在表单上,用户将按下刷新按钮来刷新数据库中的数据 这是我的密码 public partial class DocListView : UserControlListBase { private ScecoBillDataScope _scecoBill

我的小WPF代码给了我这个错误 调用线程无法访问此对象,因为另一个线程拥有它 我知道它到底在说什么,但我无法理解如何修复它。我尝试过不同的事情,但没有运气,我承认我不擅长任务库

这就是我想要达到的目标

  • 加载WPF表单时加载数据-这是正常的
  • 在表单上,用户将按下刷新按钮来刷新数据库中的数据
  • 这是我的密码

    public partial class DocListView : UserControlListBase
    {
        private ScecoBillDataScope _scecoBillDataScope;
        public EntityCollection<ScecoBillEntity> ScecoBills = new EntityCollection<ScecoBillEntity>();
    
       public DocListView()
        {
            InitializeComponent();
            LoadData();
        }
    
    
       private async void LoadData()
        {
            await Task.Run(() =>
            {
    
                _scecoBillDataScope.FetchData();
            });
            var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);
    
            await Dispatcher.BeginInvoke(new ThreadStart(()=> LayoutRoot.DataContext = collectionView));
    
         }
    
      private void BbiRefresh_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
        {
            _scecoBillDataScope.Reset();
            LoadData();
            e.Handled = true;
        }}
    
    公共部分类DocListView:UserControlListBase
    {
    专用ScecoBillDataScope\u ScecoBillDataScope;
    public EntityCollection ScecoBills=new EntityCollection();
    公共文档列表视图()
    {
    初始化组件();
    LoadData();
    }
    私有异步void LoadData()
    {
    等待任务。运行(()=>
    {
    _scecoBillDataScope.FetchData();
    });
    var collectionView=CollectionViewSource.GetDefaultView(\u scecoBillDataScope.ScecoBills);
    等待Dispatcher.BeginInvoke(新线程开始(()=>LayoutRoot.DataContext=collectionView));
    }
    私有void BbiRefresh_ItemClick(对象发送者,DevExpress.Xpf.bar.ItemClickEventArgs e)
    {
    _scecoBillDataScope.Reset();
    LoadData();
    e、 已处理=正确;
    }}
    
    实际上,当我单击这一行的刷新按钮时,就会出现错误\u scecoBillDataScope.FetchData()
    请给我一些建议

    您的问题是这一行:

    await Dispatcher.BeginInvoke(new ThreadStart(()=> LayoutRoot.DataContext = collectionView));
    
    您只需创建一个新线程,就必须在GUI线程上实际调度:

    Application.Current.Dispatcher.Invoke(() =>
    {
        LayoutRoot.DataContext = collectionView;
    });
    

    看起来您希望在UI线程中执行某些操作

    var uiThread = TaskScheduler.FromCurrentSynchronizationContext();
    
    Task.Factory.StartNew(() =>
    {
        // I assumed that It returns boolean value
        _scecoBillDataScope.FetchData();
    }).ContinueWith(x =>
    {
        // Here you can put the code to work on the UI thread.
        if (x.Result)
        {
              var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);
              LayoutRoot.DataContext = collectionView;
        }
    
    }, uiThread);
    
    正如您所知,您可以使用
    Dispatcher
    class

    但是,还有另一种方法可以向UI线程请求某些内容

    var uiThread = TaskScheduler.FromCurrentSynchronizationContext();
    
    Task.Factory.StartNew(() =>
    {
        // I assumed that It returns boolean value
        _scecoBillDataScope.FetchData();
    }).ContinueWith(x =>
    {
        // Here you can put the code to work on the UI thread.
        if (x.Result)
        {
              var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);
              LayoutRoot.DataContext = collectionView;
        }
    
    }, uiThread);
    
    我希望有帮助


    谢谢。

    由于您的收集项目是绑定到视图的数据,因此您必须将其视为UI的一部分


    尝试从
    任务中加载新集合。运行
    ,然后在UI线程上通过现有项目复制它们。因此,新集合构建在线程池线程(
    Task.Run
    )上,然后从UI线程修改数据绑定集合项。

    Task.Run(()=>return FetchDataFromDB();)。继续((o)=>使用o.Result更新UI)您的FetchData()方法不应尝试更新其他线程所拥有的任何控件。@NawedNabiZada正如您所建议的,我做了此更改,但仍然没有成功,这是因为我的集合是INotifyChangedProperty感知的。private async void LoadData(){var collectionView=CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);wait Task.Run(()=>_scecoBillDataScope.FetchData()).ContinueWith((o)=>LayoutRoot.DataContext=collectionView);}那么
    FetchData()是什么呢
    实际情况如何?@Shax由于您的收藏项目与视图相关联,因此您必须将它们视为UI的一部分。请尝试从
    任务中加载一个新集合。运行
    ,然后在UI线程上复制它们到现有项目上。不,我的朋友没有解决我的问题,但感谢您花时间帮助我。不,我的朋友没有解决我的问题,感谢您花时间帮助我。is'\u scecoBillDataScope.FetchData();'在UI线程上运行?