We have a grid listening to update messages that come in real time. If the primary key in message is found in grid, the existing row will be updated. The searching code looks like:
UltraGridRow targetRow = null; this.DataTable.DefaultView.Sort = "key"; int targetRowViewIndex = this.DataTable.DefaultView.Find(key); if (targetRowViewIndex != -1) { try { targetRow = _grid.Rows.GetRowWithListIndex(targetRowViewIndex); }
If not found a new row will be inserted.
During testing i notice the datatable sometimes contains less rows than it should do(e.g. datatable has 1200 rows while the grid has 1400). Sometimes _grid.Rows is null which throws exceptions. These two cases caused existing row not found.
Any thoughts? it is very hard to reproduce. i left the grid open overnight and was able to debug this morning.
Thanks,
Xiaojun
Thanks. i was already checking this.InvokeRequired before searching. i added a breakpoint at this line. So first time call returns true and second time false.
Sometimes first time call is false which caused grid.Rows null. Will dig more into threading part.
The RowsCollection instance returned from the Rows property is lazily created, and theoretically the Rows property should never return null. The one instance where this can happen is when cross-thread calls to the UltraGrid's public members are not marshalled properly. Simply put, you should use the BeginInvoke method when accessing the grid from a different thread than the one on which it was created. There are other articles on MSDN (and our site as well) that discuss the proper way to communicate with a control when you are on a different thread.