Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在BindingList中查找对象_C#_Winforms_Bindinglist - Fatal编程技术网

C# 在BindingList中查找对象

C# 在BindingList中查找对象,c#,winforms,bindinglist,C#,Winforms,Bindinglist,我有一个异步BindingList,其中包含在工作线程上操作并绑定到主UI线程上BindingSource的对象,BindingSource绑定到DataGridView 是否有可能在BindingList中找到对象而无需遍历该列表 我看过LINQ的引擎盖,它基本上是一个糖衣foreach循环。从我的理解来看,如果我实现IBindingList.Find()它只不过是一个for循环 我已经“尝试”将我的BindingList同步/映射到一个字典,该字典镜像我的BindingList,并使用该字典

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

是否有可能在BindingList中找到对象而无需遍历该列表

我看过LINQ的引擎盖,它基本上是一个糖衣foreach循环。从我的理解来看,如果我实现IBindingList.Find()它只不过是一个for循环

我已经“尝试”将我的BindingList同步/映射到一个字典,该字典镜像我的BindingList,并使用该字典定位对象,并将结果(索引)传递到我的BindingList,但这不起作用,因为添加和删除对象的次数太多,我无法保持组织

这是一款高性能应用程序,用于处理来自股市的实时高频数据。这就是为什么我不能遍历BindingList,它效率太低了


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

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

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

显然,您在这里有一个直接的权衡,即更大的内存使用和插入时间,维护两个列表,但对于快速勾选数据,对于改进查找时间来说,这通常是一个非常可接受的权衡

像使用
绑定列表一样使用该类,但是当需要快速查找项时,请使用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();
    }
}
公共类FastLookupBindingList:BindingList
{
私有只读IDictionary _dict=new Dictionary();
私有只读函数_keyFunc;
公共快速查找绑定列表(Func keyFunc)
{
_keyFunc=keyFunc;
}
公共FastLookupBindingList(Func-keyFunc,IList sourceList):基本(sourceList)
{
_keyFunc=keyFunc;
foreach(sourceList中的var项)
{
变量键=_键函数(项);
_添加指令(键、项);
}
}
公共TVal快速查找(TKey)
{
特瓦尔瓦尔;
_dict.TryGetValue(键,输出值);
返回val;
}
受保护的覆盖无效插入项(int索引,TVal)
{
_dict.Add(_keyFunc(val),val);
base.InsertItem(索引,val);
}
受保护的覆盖无效集合项(整数索引,TVal val)
{
var key=_keyFunc(val);
_dict[key]=val;
base.SetItem(索引,val);
}
受保护的覆盖void removietem(int索引)
{
var项目=该[指数];
变量键=_键函数(项);
_删除指令(键);
基本删除项(索引);
}
受保护的覆盖无效ClearItems()
{
_格言(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);
    }
公共类人物
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
私有void simpleButton1_单击(对象发送方,事件参数e)
{
var keyedBindingList=新的FastLookupBindingList(p=>p.Id)
{
新人{Id=1,Name=“Joe”},
新人{Id=2,Name=“Josephine”}
};
var person=keyedBindingList.FastFind(2);
var unkonwn=keyedBindingList.FastFind(4);
}

thx stevenP!我从没见过你的解决办法。我现在要实现它,看看它是如何工作的。它看起来不错,这是我之前尝试的,但无法同步,你如何使这个线程安全。我们有相同的用例,背景线程更新索引绑定列表。但是,使用您的实现会导致同步问题。到处添加锁定也会影响性能。是否可以使用ISynchronizeInvoke.Invoke进行更新?例如,使用后台工作程序执行检索/操作数据的长时间运行任务,然后在数据准备好后,调用Invoke进入UI线程并更新BindingList?