This is a migrated thread and some comments may be shown as answers.

NullReferenceException when bound data changed on non-UI thread

2 Answers 365 Views
GridView
This is a migrated thread and some comments may be shown as answers.
John
Top achievements
Rank 1
John asked on 05 Feb 2013, 08:56 PM
When I sort my grid on certain columns and then change the data bound to the grid from a thread other than the main UI thread, I sometimes get a null reference exception.

My setup is basically this:

_gridView.DataSource = myObject.Children;
// user sorts grid
// user requests update from server
make BackgroundWorker to pull from server and update myObject.Children (fields of existing objects and add/remove from list)
show progress dialog on UI thread while data is being pulled from server and put into Children on BackgroundWorker thread


I get this exception:
System.NullReferenceException  {"Object reference not set to an instance of an object."}
   at Telerik.Collections.Generic.AvlTree`1.FixInsert(AvlTreeNode`1 t, AvlTreeNode`1 u, Int32[] ad, Int32 n)
   at Telerik.Collections.Generic.AvlTree`1.Insert(Int32 index, ValueT value)
   at Telerik.Collections.Generic.AvlTree`1.InsertWithDuplicates(ValueT value)
   at Telerik.Collections.Generic.AvlTree`1.Add(ValueT item)
   at Telerik.WinControls.Data.AvlIndex`1.Perform()
   at Telerik.WinControls.Data.AvlIndex`1.get_Items()
   at Telerik.WinControls.Data.RadDataView`1.get_Items()
   at Telerik.WinControls.Data.RadCollectionView`1.GetEnumerator()
   at Telerik.WinControls.UI.GridViewInfo.Refresh()
   at Telerik.WinControls.UI.GridViewInfo.get_ChildRows()
   at Telerik.WinControls.UI.GridViewTemplate.get_ChildRows()
   at Telerik.WinControls.UI.GridViewRowInfo.get_Index()
   at Telerik.WinControls.UI.GridDataRowElement.UpdateAlternatingRowColor()
   at Telerik.WinControls.UI.GridDataRowElement.ApplyCustomFormatting()
   at Telerik.WinControls.UI.GridRowElement.UpdateInfo()
   at Telerik.WinControls.UI.GridDataRowElement.UpdateInfo()
   at Telerik.WinControls.UI.GridRowElement.Initialize(GridViewRowInfo rowInfo)
   at Telerik.WinControls.UI.GridRowElement.Attach(GridViewRowInfo row, Object context)
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.InsertElement(Int32 position, IVirtualizedElement`1 element, T data)
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.UpdateElement(Int32 position, T data)
   at Telerik.WinControls.UI.ScrollableRowsContainerElement.UpdateElement(Int32 position, GridViewRowInfo data)
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureElements()
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
   at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
   at Telerik.WinControls.UI.RowsContainerElement.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
   at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
   at Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout()
   at Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayoutCallback(ILayoutManager manager)



Looking at my worker thread state when this exception occurs, I get this more complete looking call stack.  It looks like this should perhaps being doing an Invoke to move these changes to the grid back to the UI thread. 

[Managed to Native Transition] 
mscorlib.dll!System.Type.IsVisible.get() + 0x23 bytes  
System.dll!System.SecurityUtils.MethodInfoInvoke(System.Reflection.MethodInfo method, object target, object[] args) + 0x30 bytes   
System.dll!System.ComponentModel.ReflectPropertyDescriptor.GetValue(object component) + 0x5f bytes 
Telerik.WinControls.dll!Telerik.WinControls.Data.RadListSource<System.__Canon>.GetBoundValue(object dataBoundItem, string propertyName) + 0x3a bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.BoundAccessor.this[Telerik.WinControls.UI.GridViewRowInfo].get(Telerik.WinControls.UI.GridViewRowInfo row) + 0xb7 bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewDateTimeColumn.GetValue(Telerik.WinControls.UI.GridViewRowInfo row, Telerik.WinControls.UI.GridViewDataOperation operation) + 0x15 bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewRowInfoComparer.CompareRows(Telerik.WinControls.UI.GridViewRowInfo x, Telerik.WinControls.UI.GridViewRowInfo y, Telerik.WinControls.Data.SortDescriptorCollection context) + 0x93 bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewRowInfoComparer.Compare(Telerik.WinControls.UI.GridViewRowInfo x, Telerik.WinControls.UI.GridViewRowInfo y) + 0xe bytes
Telerik.WinControls.dll!Telerik.Collections.Generic.AvlTree<Telerik.WinControls.UI.GridViewRowInfo>.Insert(Telerik.WinControls.UI.GridViewRowInfo value, bool duplicateallowed, bool overwrite) + 0x114 bytes  
Telerik.WinControls.dll!Telerik.Collections.Generic.AvlTree<System.__Canon>.InsertWithDuplicates(System.__Canon value) + 0x32 bytes
Telerik.WinControls.dll!Telerik.Collections.Generic.AvlTree<System.__Canon>.Add(System.__Canon item) + 0x5 bytes   
Telerik.WinControls.dll!Telerik.WinControls.Data.AvlIndex<Telerik.WinControls.UI.GridViewRowInfo>.Perform() + 0x2ff bytes  
Telerik.WinControls.dll!Telerik.WinControls.Data.AvlIndex<Telerik.WinControls.UI.GridViewRowInfo>.Items.get() + 0x10 bytes 
Telerik.WinControls.dll!Telerik.WinControls.Data.RadDataView<System.__Canon>.Items.get() + 0xe bytes   
Telerik.WinControls.dll!Telerik.WinControls.Data.RadCollectionView<Telerik.WinControls.UI.GridViewRowInfo>.GetEnumerator() + 0x11 bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewInfo.Refresh() + 0x213 bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewInfo.ChildRows.get() + 0x1f bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewTemplate.ChildRows.get() + 0xa bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ViewInfoTraverser.SetCollectionForStage(bool initializeCollection) + 0x138 bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ViewInfoTraverser.ChangeCollectionForward() + 0x49 bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ViewInfoTraverser.MoveNextCore() + 0x33 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ViewInfoTraverser.MoveNext() + 0x3a bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTraverser.MoveNextCore() + 0x42 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTraverser.MoveNext() + 0xd bytes   
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.ItemScroller<Telerik.WinControls.UI.GridViewRowInfo>.UpdateScrollRange() + 0x60 bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.RowScroller.UpdateScrollRange() + 0x19 bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTableElement.UpdateWhenItemChanged(Telerik.WinControls.UI.DataViewChangedEventArgs args) + 0x94 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTableElement.UpdateViewCore(object sender, Telerik.WinControls.UI.DataViewChangedEventArgs args) + 0x1ed bytes 
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTableElement.UpdateView(object sender, Telerik.WinControls.UI.DataViewChangedEventArgs args) + 0x4e bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTableElement.ProcessTemplateEvent(Telerik.WinControls.UI.GridViewEvent eventData) + 0xc7 bytes 
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridTableElement.Telerik.WinControls.UI.IGridViewEventListener.ProcessEvent(Telerik.WinControls.UI.GridViewEvent eventData) + 0x196 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewEventProcessEntity.ProcessCollection(Telerik.WinControls.UI.GridViewEvent gridEvent, Telerik.WinControls.UI.PriorityWeakReferenceList list, Telerik.WinControls.UI.GridEventProcessMode processMode) + 0xa4 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewEventProcessEntity.ProcessEvent(Telerik.WinControls.UI.GridViewEvent gridEvent) + 0x35 bytes   
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewSynchronizationService.NotifyListeners(Telerik.WinControls.UI.GridViewEvent gridEvent) + 0x8a bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewSynchronizationService.FlushEvents() + 0xda bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewSynchronizationService.DispatchEvent(Telerik.WinControls.UI.GridViewEvent gridEvent) + 0x61 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewSynchronizationService.DispatchEvent(Telerik.WinControls.UI.GridViewTemplate template, Telerik.WinControls.UI.GridViewEvent eventData, bool postUI) + 0x18b bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewTemplate.DispatchEvent(Telerik.WinControls.UI.GridViewEvent gridEvent, bool postUI) + 0xb bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewTemplate.DispatchDataViewChangedEvent(object sender, Telerik.WinControls.UI.DataViewChangedEventArgs args) + 0xa2 bytes
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewTemplate.OnViewChanged(object sender, Telerik.WinControls.UI.DataViewChangedEventArgs e) + 0x49 bytes  
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewTemplate.CollectionView_CollectionChanged(object sender, Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e) + 0x2e bytes 
Telerik.WinControls.dll!Telerik.WinControls.Data.RadCollectionView<System.__Canon>.OnCollectionChanged(Telerik.WinControls.Data.NotifyCollectionChangedEventArgs args) + 0x3f bytes
Telerik.WinControls.dll!Telerik.WinControls.Data.RadDataView<Telerik.WinControls.UI.GridViewRowInfo>.ProcessCollectionChanged(Telerik.WinControls.Data.NotifyCollectionChangedEventArgs args) + 0x11b bytes
Telerik.WinControls.dll!Telerik.WinControls.Data.RadCollectionView<System.__Canon>.source_CollectionChanged(object sender, Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e) + 0x23 bytes   
Telerik.WinControls.dll!Telerik.WinControls.Data.RadListSource<System.__Canon>.OnCollectionChanged(Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e) + 0x1e bytes   
Telerik.WinControls.dll!Telerik.WinControls.Data.RadListSource<System.__Canon>.ChangeItem(int index, System.__Canon item, string propertyName) + 0xc2 bytes
Telerik.WinControls.dll!Telerik.WinControls.Data.RadListSource<System.__Canon>.currencyManager_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + 0x125 bytes  
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.OnListChanged(System.ComponentModel.ListChangedEventArgs e) + 0x15 bytes 
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.List_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + 0x53e bytes  
System.Data.Entity.dll!System.Data.Objects.ObjectView<System.__Canon>.OnListChanged(System.ComponentModel.ListChangedEventArgs changeArgs) + 0x1f bytes
System.Data.Entity.dll!System.Data.Objects.ObjectView<DataAccess.Child>.System.Data.Objects.IObjectView.EntityPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + 0x4d bytes  
System.Data.Entity.dll!System.Data.Objects.ObjectViewListener.EntityPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + 0x31 bytes  
System.Data.Entity.dll!System.Data.Objects.DataClasses.StructuralObject.OnPropertyChanged(string property) + 0x31 bytes
System.Data.Entity.dll!System.Data.Objects.DataClasses.StructuralObject.ReportPropertyChanged(string property) + 0x23 bytes
System.Data.Entity.dll!System.Data.Objects.DataClasses.EntityObject.ReportPropertyChanged(string property) + 0x50 bytes




2 Answers, 1 is accepted

Sort by
0
Brad
Top achievements
Rank 1
answered on 07 Feb 2013, 05:14 PM
I have just worked on a form with multiple data bound GridViews that update the database on a BackgroundWorker. To prevent errors like this I call the GridView SuspendLayout and BeginUpdate functions before starting the background worker. In the RunWorkerCompleted event I call EndUpdate and ResumeLayout.

I put them in a couple functions like so, and call them before running the background worker and on completion:

private void setGridsToBeginUpdate()
{
    this.radGridView1.SuspendLayout();
    this.radGridView1.BeginUpdate();
    //Repeat for other Grids...
}
private void setGridsToEndUpdate()
{
    this.radGridView1.EndUpdate();
    this.radGridView1.ResumeLayout();
    //Repeat for other Grids...
}
private void button1_Click(object sender, EventArgs e)
{     
      radGridView.EndEdit();
    setGridsToBeginUpdate();
    //backgroundWorker.RunWorkerAsync()
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    setGridsToEndUpdate();
}
0
Julian Benkov
Telerik team
answered on 08 Feb 2013, 09:39 AM
Hi John,

RadGridView does not support cross-thread update operations. This behavior concerns all our UI components and the whole Windows Forms GUI. More information about this topic and how to use the UI in a multithreaded application you can find in the MSDN Documentation.

I hope this information is useful. Let me know if you need further assistance.

Regards,
Julian Benkov
the Telerik team
Q3'12 SP1 of RadControls for WinForms is out now. See what's new.
Tags
GridView
Asked by
John
Top achievements
Rank 1
Answers by
Brad
Top achievements
Rank 1
Julian Benkov
Telerik team
Share this question
or