When using controls such as ListView to load data, the first thing to think about is ObservableCollection, which is good, if you add, delete, modify data, the UI will be updated automatically.
However, if you do not need to add or delete, display large data volume, how does this thing load performance?
Do an experiment.
1. Prepare the data, create 20,000 files on the local disk, and load it into the ListView.
var Testpath = @ "D:\TestLargeData\Test10000"; if (! Directory.Exists (Testpath)) directory.createdirectory (testpath); else { MessageBox.Show ("Test file has been created"); return; } for (int i = 0; i < 20000; i++) file.create (Path.Combine (Testpath, Path.getrandomfilename ()));
2. Loading with obserablecollection
#region Data source 1//<summary>///files and directories in current directory, display in LIS Tview//</summary> observablecollection<fileitem> allFiles1 = new Observablecollection<file Item> (); <summary>///files and directories in current directory, display in ListView///</summary> ; Public observablecollection<fileitem> AllFiles1 {get {return allFiles1;} set {if (allFiles1! = value) AllFiles1 = value; Notifypropertychanged ("AllFiles1"); }} #endregion #region Load Data Method---1//<summary>//when current direct Ory path Change, refresh ListView///</summary> public void Refresh1 () {Loadlastfi Les (); }//<summary>//Loading last file Task///</Summary> void Loadlastfiles () {var files = directory.enumeratefilesystementries (Testpath); DateTime dtbegin = DateTime.Now; LogHelper.Log ("1====loading begin:"); foreach (var pagefile in files) {Invoke (delegate {allFiles1. ADD (Getfileitem (pagefile)); }); } LogHelper.Log ("1====loading OK:" + (Datetime.now-dtbegin). TotalSeconds); LogHelper.Log ("1====current itemscount:" + allFiles1.Count.ToString ()); } #endregion
3. Loading with List
#region DataSource 2//<summary>//files and directories in current directory, display in ListView///</summary> list<fileitem> allFiles2 = new list<fileitem> (); <summary>///files and directories in current directory, display in ListView///</summary> ; Public list<fileitem> AllFiles2 {get {return allFiles2;} set {if (AllFiles2! = value) AllFiles2 = value; Notifypropertychanged ("AllFiles2"); }} #endregion #region Load Data Method---2//<summary>//when current direct Ory path Change, refresh ListView///</summary> public void Refresh2 () {Loadlastfi Les2 (); }//<summary>//Loading last file Task///</summary> void LoadLastFiles2 () {var files = directory.enumeratefilesystementries (Testpath); AllFiles2 = new list<fileitem> (); DateTime dtbegin = DateTime.Now; DateTime Dtlastrefresh = DateTime.Now; LogHelper.Log ("2====loading begin:"); foreach (string file in files) {Allfiles2.add (Getfileitem (file)); Notifypropertychanged ("AllFiles2"); } LogHelper.Log ("2====loading OK:" + (Datetime.now-dtbegin). TotalSeconds); LogHelper.Log ("2====current itemscount:" + AllFiles2.Count.ToString ()); } #endregion
The results of this comparison are:
04:23:13 235 | 1====loading begin:
04:23:13 850 | 1====loading ok:0.615
04:23:13 851 | 1====current itemscount:73338
04:23:15 458 | 2====loading begin:
04:23:15 961 | 2====loading ok:0.503
04:23:15 962 | 2====current itemscount:73338
The comparison found that two of the difference is not small.
4. The above experiment, the data is in the main line preempted, the actual data loading is generally using the line preempted, so the modified code is as follows:
5. Obserablecollection loading and dropping in the thread, need invoke, as follows:
#region Load Data Method---1//<summary>//When current directory path change, refresh Lis Tview//</summary> public void Refresh1 () {//loadlastfiles (); Allfiles1.clear (); Thread thread1 = new Thread (new ThreadStart (loadlastfiles)); Thread1. Start (); }//<summary>//Loading last file Task///</summary> void Loadlastfiles () {var files = directory.enumeratefilesystementries (Testpath); DateTime dtbegin = DateTime.Now; LogHelper.Log ("1====loading begin:"); foreach (var pagefile in files) {Invoke (delegate {allFiles1. ADD (Getfileitem (pagefile)); }); } LogHelper.Log ("1====loading OK:" + (Datetime.now-dtbegin). TotalSeconds); LogHelper.Log ("1====current itemscount:" +AllFiles1.Count.ToString ()); } #endregion
6.list also put in the thread, this need to pass the ListView over, refresh items, as follows
#region DataSource 2//<summary>//files and directories in current directory, display in LISTV Iew//</summary> list<fileitem> allFiles2 = new list<fileitem> (); <summary>///files and directories in current directory, display in ListView///</summary> ; Public list<fileitem> AllFiles2 {get {return allFiles2;} set {if (AllFiles2! = value) AllFiles2 = value; Notifypropertychanged ("AllFiles2"); }} #endregion #region Load Data Method---2//<summary>//when current direct Ory path Change, refresh ListView///</summary> public void Refresh2 () {//loadlast Files2 (); Thread thread2 = new Thread (new ThreadStart (LoadLastFiles2)); Thread2. Start (); }//<summary> Loading last file task//</summary> void LoadLastFiles2 () {var files = Direc Tory. Enumeratefilesystementries (Testpath); AllFiles2 = new list<fileitem> (); DateTime dtbegin = DateTime.Now; DateTime Dtlastrefresh = DateTime.Now; LogHelper.Log ("2====loading begin:"); foreach (string file in files) {Allfiles2.add (Getfileitem (file)); Notifypropertychanged ("AllFiles2"); Invoke (Delegate {This.tstLv.Items.Refresh (); }); Dtlastrefresh = DateTime.Now; } notifypropertychanged ("AllFiles2"); LogHelper.Log ("2====loading OK:" + (Datetime.now-dtbegin). TotalSeconds); LogHelper.Log ("2====current itemscount:" + AllFiles2.Count.ToString ()); } #endregion
After several rounds of testing, it is found that the list is significantly slower
04:42:02 493 | 1====loading begin:
04:42:05 287 | 1====loading ok:2.7932793
04:42:05 288 | 1====current itemscount:73338
04:42:07 192 | 2====loading begin:
04:42:26 276 | 2====loading ok:19.0839082
04:42:26 277 | 2====current itemscount:73338
04:42:43 277 | 2====loading begin:
04:43:04 188 | 2====loading ok:20.9110909
04:43:04 189 | 2====current itemscount:73338
04:43:05 838 | 1====loading begin:
04:43:08 511 | 1====loading ok:2.6732673
04:43:08 512 | 1====current itemscount:73338
This time, the advantages of obserablecollection are very obvious.
7. When using the list, refresh each additional data, which is a bit wasteful here.
There are two ways: one is to refresh each number of data (for example, 200) and refresh it every 0.1 seconds. Considering the user's operation, the user is less likely to operate within 0.1 seconds, the hand will not be so fast.
Tick load list optimization code is as follows:
void LoadLastFiles2 () {var files = directory.enumeratefilesystementries (Testpath); AllFiles2 = new list<fileitem> (); DateTime dtbegin = DateTime.Now; DateTime Dtlastrefresh = DateTime.Now; LogHelper.Log ("2====loading begin:"); foreach (string file in files) {Allfiles2.add (Getfileitem (file)); Notifypropertychanged ("AllFiles2"); if ((Datetime.now-dtlastrefresh). TotalSeconds > 0.1) {Invoke (delegate {thi S.tstlv.items.refresh (); }); Dtlastrefresh = DateTime.Now; }} notifypropertychanged ("AllFiles2"); LogHelper.Log ("2====loading OK:" + (Datetime.now-dtbegin). TotalSeconds); LogHelper.Log ("2====current itemscount:" + AllFiles2.Count.ToString ()); }
The contrast is very different:
04:46:57 739 | 1====loading begin:
04:47:00 388 | 1====loading ok:2.650265
04:47:00 389 | 1====current itemscount:73338
04:47:03 612 | 2====loading begin:
04:47:03 853 | 2====loading ok:0.2410241
04:47:03 854 | 2====current itemscount:73338
04:47:20 351 | 2====loading begin:
04:47:20 641 | 2====loading ok:0.290029
04:47:20 662 | 2====current itemscount:73338
04:47:23 235 | 1====loading begin:
04:47:25 875 | 1====loading ok:2.640264
04:47:25 876 | 1====current itemscount:73338
It seems that time-sharing load, a little meaning.
Let's take a look at the load of data volume:
Code:
List
Results
04:54:03 480 | 1====loading begin:
04:54:06 056 | 1====loading ok:2.5762576
04:54:06 057 | 1====current itemscount:73338
04:54:07 112 | 2====loading begin:
04:54:07 429 | 2====loading ok:0.3170317
04:54:07 430 | 2====current itemscount:73338
04:54:24 489 | 2====loading begin:
04:54:24 789 | 2====loading ok:0.3010301
04:54:24 790 | 2====current itemscount:73338
04:54:26 486 | 1====loading begin:
04:54:29 176 | 1====loading ok:2.690269
04:54:29 177 | 1====current itemscount:73338
It seems to be the time to set the refresh, this looks a lot faster.
As for the sub-data or time-sharing, to see the actual needs, individuals think the time-sharing is better.
Time-sharing is preferably longer, and the amount of data chunk is larger, reducing the time to refresh the UI, loading will be faster.
But if the user drag the scroll bar at the same time, the experience is not good, not smooth, the scroll bar will jump.
8. ObservableCollection also has optimized schemes, such as the following, using deferred notification data change scenarios. Online to see, I am sorry, did not find the source.
rangeobservablecollection
Modify the code as follows:
Load1
After the test, the effect is not obvious:
05:05:08 989 | 1====loading begin:
05:05:13 189 | 1====loading ok:4.2
05:05:13 191 | 1====current itemscount:73338
So, let's just go on the shelf.
Nagging so much, in fact, for the big data load, MS provides the ObservableCollection solution is good, but, want to faster, or to engage in their own.
In addition, ObservableCollection why fast, online a lot of information, research it.
Welcome to shoot Bricks!!
Reprint: Load performance Comparison of data