为了账号安全,请及时绑定邮箱和手机立即绑定

跨 UI 和非 UI 线程使用 ObservableCollection

跨 UI 和非 UI 线程使用 ObservableCollection

C#
陪伴而非守候 2021-10-09 10:23:20
我正在使用此处描述的 SortableObservableCollection 。现在我想从 UI 或非 UI 线程操作它,所以我尝试了这里描述的解决方案:using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Runtime;using System.Windows.Data;public class SortableObservableCollection<T> : ObservableCollection<T>{    private object _itemsLock = new object();    public SortableObservableCollection()        : base()    {        BindingOperations.EnableCollectionSynchronization(this, _itemsLock);    }    public SortableObservableCollection(List<T> l) : base(l)    {        BindingOperations.EnableCollectionSynchronization(this, _itemsLock);    }    public SortableObservableCollection(IEnumerable<T> l) : base(l)    {        BindingOperations.EnableCollectionSynchronization(this, _itemsLock);    }    #region Sorting    public void Sort<TKey>(Func<T, TKey> keySelector)    {        InternalSort(Items.OrderBy(keySelector));    }    public void SortDescending<TKey>(Func<T, TKey> keySelector)    {        InternalSort(Items.OrderByDescending(keySelector));    }    public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)    {        InternalSort(Items.OrderBy(keySelector, comparer));    }    private void InternalSort(IEnumerable<T> sortedItems)    {        var sortedItemsList = sortedItems.ToList();        foreach (var item in sortedItemsList)        {            Move(IndexOf(item), sortedItemsList.IndexOf(item));        }    }    #endregion // Sorting    public new void Add(T item)    {        base.Add(item);    }但是 .Net 4.5.2、WPF 桌面应用程序中的这个解决方案在移除、添加和清除方法中引发异常:System.NotSupportedException : '这种类型的 CollectionView 不支持从不同于调度程序的线程更改其 SourceCollection线。'所以,自从BindingOperations.EnableCollectionSynchronization(this, _itemsLock); 之后,我又回到使用 Application.Current.Dispatcher 方法(见下文)。机制不像上面链接的博客文章中宣传的那样工作。我的问题是:我在第一个列表中做错了什么,还是博客文章不正确,声称线程边界总是可以通过这种机制成功跨越?下面的清单是最好的,还是有更好的解决方案来管理具有跨线程绑定的 observablecollection?
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

我的问题是:我在第一个列表中做错了什么,还是博客文章不正确,声称线程边界总是可以通过这种机制成功跨越?

问题是你需要BindingOperations.EnableCollectionSynchronization在 UI 线程上调用该方法,即你需要SortableObservableCollection<T>在 UI 线程上实例化你的方法才能工作。

如果您不能保证集合将在 UI 线程上初始化,则应使用调度程序将所有修改数据绑定集合的操作编组回 UI 线程。调用BindingOperations.EnableCollectionSynchronization后台线程不会解决您的问题。


查看完整回答
反对 回复 2021-10-09
  • 1 回答
  • 0 关注
  • 309 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信