首页  >  文章  >  后端开发  >  如何在 WPF 中从后台线程安全地修改 ObservableCollections?

如何在 WPF 中从后台线程安全地修改 ObservableCollections?

Susan Sarandon
Susan Sarandon原创
2024-10-30 07:28:27615浏览

How to Safely Modify ObservableCollections from Background Threads in WPF?

UI 线程亲和性和 ObservableCollection 修改

问题概述

从 UI 线程以外的线程更新绑定到 DataGrid 的 ObservableCollection 时,可能会发生异常:“这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程更改其 SourceCollection。”

了解 UI 线程关联性

ObservableCollections 在 UI 线程上创建。因此,它们与该线程具有亲和力,这意味着只能从同一线程进行更改。尝试从另一个线程(例如后台线程)修改它们将触发异常。

解决方案:调用 UI Dispatcher

要解决此问题,请在更新 ObservableCollection 时调用 UI Dispatcher不同的线程。这会将操作委托给 UI 线程,以便安全执行。

更新了 ViewModel 代码

public void Load()
{
    matchList = new List<GetMatchDetailsDC>();
    matchList = proxy.GetMatch().ToList();

    foreach (EfesBet.DataContract.GetMatchDetailsDC match in matchList)
    {
        // This syntax invokes the UI dispatcher 
        // and modifies the ObservableCollection on the UI thread
        App.Current.Dispatcher.Invoke((Action)delegate
        {
            _matchObsCollection.Add(match);
        });
    }
}

异步数据绑定和 DataGrid 刷新

绑定DataGrid 异步并在必要时刷新它:

  1. 实现异步加载: 使用异步方法(如 AsyncDelegateCommand)将数据加载到 ObservableCollection 中。
  2. 订阅 CollectionChanged 事件: 订阅 ObservableCollection 的 CollectionChanged 事件以获取更改通知并相应更新 DataGrid。
  3. 触发 DataGrid 刷新: 使用 Items.Refresh() DataGrid 上的方法来手动刷新其数据。

示例

// Bind DataGrid to ObservableCollection
DataGrid.SetBinding(ItemsSourceProperty, new Binding("MatchObsCollection"));

// Subscribe to CollectionChanged event
MatchObsCollection.CollectionChanged += (s, e) =>
{
    DataGrid.Items.Refresh();
};

通过遵循这些准则,您可以安全地异步更新 ObservableCollections 并绑定 DataGrid,同时确保在正确的线程。

以上是如何在 WPF 中从后台线程安全地修改 ObservableCollections?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn