ListCollectionView.Refresh issue

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近项目里面发现的一个bug。我们用 ListCollectionView 作为ListBox 的数据源,但是发现在增加和删除 ListCollectionView 中的数据时,它和它的 SourceCollection 数据不同步。 在删除的时候 SourceCollection 已经没有那一项,但是 ListCollectionView 中还是有。 本来以为是 ListCollectionView 的bug, 所以就尝试每次修改数据内容时都 CommitNew(), CommitEdit(), 然后 Refresh() 这个 View。 依然会有这个错误。</span>

然后打开debug exception 后, 发现 ListCollectionView 的SourceCollection 在 CollectionChanged 时间中会抛出异常。 这个异常导致在 SourceCollection 数据内容修改后,view 无法正常更新。因为 view 的更新就是依赖 SourceCollection 的CollectionChanged 时间来更新自己。所以每次这个事件抛出异常, view中的数据就肯定会错。这个异常是说一个已经不在 collection 中的项出发了
CollectionChanged 事件。 我们是用 DynamicObservableCollection 来作为 SourceCollection。 它是我们自己实现的一个集合类。原本认为这个类已经支持多线程。但是实际上,它只是支持 CollectionChanged 的时间处理函数在触发该事件的线程上执行。比如如果是主线程触发了 CollectionChanged 那么事件处理就会在主线程中执行。

这个实现的问题在于,它无法阻止不同线程同时修改这个集合, 甚至同时修改集合中的同一项也是合法的。这就导致不同线程增,减这个集合元素的时候会同时触发 CollectionChanged 事件, 而且不能保证引起这个事件的数据项肯定是存在于这个集合当中的。例如一个线程加入了一个数据项, index = 2, 这时候另外一个线程删除了 index = 2 这一项。然后,加入这一项的线程触发了 SourceCollection 事件,它准备开始执行处理程序, 但是处理程序发现集合中不存在这一项,于是抛出异常。

目前我们的处理是保证对 ListCollectionView 的操作都在主线程中进行。更好的方式是保证 DynamicObservableCollection 的动作会同步,目前还没有实现。

protected virtual void OnCollectionChangedMultiItem(NotifyCollectionChangedEventArgs e)
{
   NotifyCollectionChangedEventHandler handlers = this.CollectionChanged;
   if (handlers != null)
   {
      foreach (NotifyCollectionChangedEventHandler handler in handlers.GetInvocationList())
      {
         if (handler.Target is CollectionView)
            ((CollectionView)handler.Target).Refresh();
         else
            handler(this, e);
      }
   }
}
时间: 2024-10-13 15:06:31

ListCollectionView.Refresh issue的相关文章

ServicesController 的使用

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

Refresh Taskbar Icons

Issue: I have a few Programs Pinned to my taskbar. These Programs reside on an external drive that is not available at boottime. My problem is, that windows does not display the icons for these programs - instead it shows the defautl placeholder.How

asp.net中bin目录下的 dll.refresh文件

首先找到了这篇文章http://www.cnblogs.com/haokaibo/archive/2010/07/31/1789342.html 然后找到一篇英文的文章http://monsur.xanga.com/2006/02/03/dll-refresh-and-asp-net/ The question is so simple I wonder why I haven’t encountered it before:  If web projects in Visual Studio

Part 31 AngularJS page refresh problem

What is the issue : When you navigate to http://localhost/students, you will see list of students as shown below Click on any student name. For example when you click on Mark, you will see mark details and the URL in the address bar is http://localho

How to Fix GNOME License Not Accepted Issue on CentOS 7

This post assume that you have just finished the Gnome GUI installation on CentOS 7 by using "yum groupinstall "GNOME Desktop" "Graphical Administration Tools" -y" command. Previously you are running a minimum CentOS 7, only

Python pandas &#39;HDFStore requires PyTables&#39; Issue

Python pandas 'HDFStore requires PyTables' Issue 在运行mobike.py过程中,一直报错,原因是pip install tables命令中安装的pytables文件其实是存在问题的,后续有人修正了这个问题并发布了新的tables库 因此在安装的时候 pip install tables==3.3.0 Python pandas 'HDFStore requires PyTables' Issue

clear ,refresh,free

itab 即是内表也是工作区的情况下,即with header line. clear itab,仅清空HEADER LINE,对内表数据存储空间不影响,保留内存区. refresh itab,不清空HEADER LINE,清除内表数据存储空间,但保存内存区. free itab,不清空HEADER LINE,清空内表数据存储空间. clear itab[],保留工作区,清空内表数据存储空间里的内容. clear <itab> . "清空不带表头行内表 clear<itab&g

java.sql.SQLException: Can not issue empty query.

1.错误叙述性说明 java.sql.SQLException: Can not issue empty query. at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:

ASP.NET OAuth:access token的加密解密,client secret与refresh token的生成

在ASP.NET OWIN OAuth(Microsoft.Owin.Security.OAuth)中,access token 的默认加密方法是: 1) System.Security.Cryptography.DpapiDataProtector.Protect() 2) Convert.ToBase64String() 3) .TrimEnd('=').Replace('+', '-').Replace('/', '_'); access token 的默认解密方法是: 1) System