I have a basic WPF-Application.It contains a Datagrid
that is bound to a AsyncObservableCollection
. When adding items to the Collection from a different thread then i'm getting the following exception at Random.
An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll
Additional information: An ItemsControl is inconsistent with its items source.
"Information for developers (use Text Visualizer to read this):\r\nThis
exception was thrown because the generator for control
'System.Windows.Controls.DataGrid Items.Count:3' with name 'logPanel' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection. The following differences were detected:\r
Accumulated count 1 is different from actual count 3. [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset).]\r
\n At index 0: Generator's item 'BorgingIskMainApp.Model.LogItem' is different from actual item 'BorgingIskMainApp.Model.LogItem'.
Some code:
Note: myLogItems
is the AsyncObservableCollection
The Binding
public MainWindow()
{
myLogItems = new AsyncObservableCollection<LogItem>();
logPanel.ItemsSource = myLogItems;
}
Initialization of the Task
System.Windows.Application.Current.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,(Action)delegate()
{
DocumentTest cg = new DocumentTest();
Task.Factory.StartNew(() => { cg.PerformWVSTest(myLogItems); });
});
My Method
public void PerformWVSTest(ObservableCollection<LogItem> dgResults)
{
try
{
dgResults.Insert(0,lgItem.CreateNewLogItem(dgResults.Count, "Start WVS-Test", true));
....
}
}
My Object
public class LogItem
{
public LogItem() {
logId = 0;
logText = String.Empty;
isSuccess = true;
}
public Int32 logId { get; set; }
public String logText { get; set; }
public Boolean isSuccess { get; set; }
public LogItem CreateNewLogItem(Int32 pLogId, String pLogText, Boolean success)
{
ADF.Diagnostics.TextFileTracer.Write(pLogText);
return new LogItem { logId = pLogId, logText = pLogText, isSuccess = success };
}
}
Anyone got an idea what might cause this exception?
Note: The exception can occur at any moment. There is no stated time or index where it Always
happens
Note 2: Code of AsyncObservableCollection
public class AsyncObservableCollection<T> : ObservableCollection<T>
{
private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
public AsyncObservableCollection()
{
}
public AsyncObservableCollection(IEnumerable<T> list)
: base(list)
{
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (SynchronizationContext.Current == _synchronizationContext)
{
// Execute the CollectionChanged event on the current thread
RaiseCollectionChanged(e);
}
else
{
// Raises the CollectionChanged event on the creator thread
_synchronizationContext.Send(RaiseCollectionChanged, e);
}
}
private void RaiseCollectionChanged(object param)
{
// We are in the creator thread, call the base implementation directly
base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (SynchronizationContext.Current == _synchronizationContext)
{
// Execute the PropertyChanged event on the current thread
RaisePropertyChanged(e);
}
else
{
// Raises the PropertyChanged event on the creator thread
_synchronizationContext.Send(RaisePropertyChanged, e);
}
}
private void RaisePropertyChanged(object param)
{
// We are in the creator thread, call the base implementation directly
base.OnPropertyChanged((PropertyChangedEventArgs)param);
}
}
Source for AsyncCollection: wpf-binding-to-an-asynchronous-collection
All credit to the designer of the object!