Rac*_*hel 9 c# .net-3.5 devexpress-windows-ui
我们有一个绑定到List<T>项目的网格.只要用户点击"刷新",就会从数据库中获取更改,并更新绑定列表.我遇到了一个问题,即重复项目被添加到网格中,我无法弄清楚原因.
数据库调用返回两个值:List<int>已更改的记录ID,以及已更改记录List<MyClass>的更新数据.我正在调试的现有代码代码找出需要更新的内容,如下所示:
public void FindUpdates(IList<MyClass> existingRecords,
IList<MyClass> updatedRecords,
List<int> updatedIds,
out IDictionary<int, int> existing,
out IDictionary<int, int> updated,
out List<int> updates,
out List<int> removes,
out List<int> adds)
{
updates = new List<int>();
removes = new List<int>();
adds = new List<int>();
existing = FindUpdated(existingRecords, updatedIds);
updated = FindUpdated(updatedRecords, updatedIds);
if (updatedIds != null)
{
// split add/update and remove
foreach (int id in updatedIds)
{
if (!existing.ContainsKey(id))
adds.Add(id);
else if (updated.ContainsKey(id))
updates.Add(id);
else
removes.Add(id);
}
WriteToLog(updatedIds, adds, updates, removes);
}
}
private IDictionary<int, int> FindUpdated(IList<MyClass> records, List<int> updatedIds)
{
IDictionary<int, int> foundItems = new Dictionary<int, int>();
if (records != null && updatedIds != null)
{
for (int i = 0; i < records.Count; i++)
{
IMyClass r = records[i] as IMyClass ;
if (r != null && !r.IsDisposed)
{
if (updatedIds.Contains(r.Id))
{
foundItems.Add(r.Id, i);
}
}
}
}
return foundItems;
}
Run Code Online (Sandbox Code Playgroud)
调用的结果FindUpdates()是我获得了一条Dictionary<Id, Data>现有记录,一条Dictionary<Id, Data>用于替换它们的更新记录,以及一个List<int>应从数据源添加,删除或更新项目的ID.
有时,一个记录会被添加到网格中两次,我不能在我的生活中找出这个代码出错的地方.
我从其中一个实例中提取了日志文件,并且可以清楚地看到以下事件序列:
WriteToLog() 从第二个添加告诉我
updatedIds 包含值1,2和3adds 包含1和2updates 包含3基于其他日志条目,我可以清楚地看到项目#2之前已添加,并且从未被删除,因此它应该在existingRecords变量中显示在updates变量中,而不是在变量中adds.此外,项目#2在第一个添加和第二个之间成功更新了几次,因此理论上的代码应该可行.我还有UI的屏幕截图,同时显示数据网格中第2项的副本.
笔记...
IsDisposed仅在项目的重写.Dispose()方法中设置为true .我不认为这会发生.
编辑:从那时起我添加了一个日志语句,并且可以验证在发生这种情况时IsDisposed未设置true.
对于一些不同的用户来说,这已经发生了几次,所以这不仅仅是一次性的事情.我无法按需重现问题.
记录网格可能相当大,平均有几千个项目.
我没有排除DB调用返回无效值的想法,或者没有相同项目的列表,但我不知道这会如何影响结果
有一次我能够看到这个bug在行动,我们正在运行一些测试,而其他用户正在相当频繁地修改记录#2
这一切都在后台线程中运行
根据日志,这只是当时运行一次.之前一分钟,以及接下来的2分钟之后就开始了.
从日志文件中,我可以看到项目#2在第二次错误添加之前已经正确更新了几次,因此这段代码之前几次与现有数据集一起工作.
上面显示的代码中是否有任何可能导致这种情况发生的事情?或者也许是C#中一个罕见的已知问题,这可能发生在我不知道的地方?
List<T>使用上面的代码没有理由找不到现有项目。
Dictionary<int,int>当我注意到输出值中包含包含项目 Id 和现有列表中项目索引的值时,我应该在脑海中敲响警钟。
发生的情况是使用 删除项目existingRecords[existing[id]],其中existing[id]将返回 中项目的索引existingRecords。为了使其发挥作用,必须从最大索引向下删除项目。如果较小的索引在较大的索引之前被删除,则较大的索引现在不正确 1 个位置,并且错误的项目将被删除。
至于为什么我得到重复的项目,那是因为正在维护两个集合,一个用于确定项目是否是新的/更新的/删除的,另一个是绑定在 UI 中显示的。第一个集合未正确更新,而第二个集合未正确更新,导致项目可能会多次添加到 UI 集合中。
我的短期解决方案是对集合进行排序,removes以确保它按每个项目的索引按降序排序。我的长期解决方案是重写代码。:)
| 归档时间: |
|
| 查看次数: |
496 次 |
| 最近记录: |