正在BindingList中查找对象

本文关键字:对象 查找 BindingList 正在 | 更新日期: 2023-09-27 18:26:42

我有一个异步绑定列表,其中包含在工作线程上操作并绑定到主UI线程上的BindingSource的对象,BindingSource绑定到DataGridView。

是否可以在我的BindingList中定位对象,而无需遍历列表?

我看过LINQ的引擎盖下面,它基本上是一个裹着糖的前臂环。根据我的理解,如果我实现IBindingList.Find(),它只不过是一个for循环。。。

我已经"尝试"将我的BindingList同步/映射到一个字典,该字典镜像了我的Binding列表,并使用该字典定位对象,并将结果(索引)传递到我的BindingList,但这不起作用,因为添加和删除对象太多,我无法保持有序。

这是一款高性能的应用程序,可以处理来自股市的实时高频数据。这就是为什么我不能迭代BindingList的原因,它太低效了。

有人能给我一些建议和/或解决方案吗。

正在BindingList中查找对象

所以某种快速查找绑定列表。。。这是我之前准备的。

这就是你提到的"同步/映射"方法。我以前在快速勾选数据时使用过这种方法,主要瓶颈是在列表中查找项目。我相信我已经涵盖了保持同步或"有组织"所需的所有方法。你可能需要为AddRange添加一个测试——我手头没有反编译器,我不确定它是否只是调用InsertItem。

显然,在维护两个列表的同时,您需要在更大的内存使用量和插入时间之间进行直接的权衡,但对于快速勾选的数据,这通常是一个非常可接受的权衡,可以改善查找时间。

像使用BindingList一样使用类,但当您需要快速查找项目时,请使用FastFind方法。

public class FastLookupBindingList<TKey, TVal> : BindingList<TVal>
{
    private readonly IDictionary<TKey, TVal> _dict = new Dictionary<TKey, TVal>();
    private readonly Func<TVal, TKey> _keyFunc;
    public FastLookupBindingList(Func<TVal, TKey> keyFunc)
    {
        _keyFunc = keyFunc;
    }
    public FastLookupBindingList(Func<TVal, TKey> keyFunc, IList<TVal> sourceList) : base(sourceList)
    {
        _keyFunc = keyFunc;
        foreach (var item in sourceList)
        {
            var key = _keyFunc(item);
            _dict.Add(key, item);
        }
    }
    public TVal FastFind(TKey key)
    {
        TVal val;
        _dict.TryGetValue(key, out val);
        return val;
    }
    protected override void InsertItem(int index, TVal val)
    {
        _dict.Add(_keyFunc(val), val);
        base.InsertItem(index, val);
    }
    protected override void SetItem(int index, TVal val)
    {
        var key = _keyFunc(val);
        _dict[key] = val;
        base.SetItem(index, val);
    }
    protected override void RemoveItem(int index)
    {
        var item = this[index];
        var key = _keyFunc(item);
        _dict.Remove(key);
        base.RemoveItem(index);
    }
    protected override void ClearItems()
    {
        _dict.Clear();
        base.ClearItems();
    }
}

用法:

public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    private void simpleButton1_Click(object sender, EventArgs e)
    {
        var keyedBindingList = new FastLookupBindingList<int, Person>(p => p.Id)
                                   {
                                       new Person {Id = 1, Name = "Joe"}, 
                                       new Person {Id = 2, Name = "Josephine"}
                                   };
        var person = keyedBindingList.FastFind(2);
        var unkonwn = keyedBindingList.FastFind(4);
    }