Adding to an observable collection with alternate thread
I am adding to an observablecollection in an alternate thread and this collection is bound to a datagrid from the wpftoolkit.
The oncollectionchanged is invoking through the main gui thread when such an event occurs.
The problem I am seeing is that most of the time the application will throw:
System.ArgumentOutOfRangeException was unhandled Message=Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index Source=mscorlib ParamName=index StackTrace: at System.ThrowHelper.ThrowArgumentOutOfRangeException() at System.Collections.Generic.List
1.get_Item(Int32 index) at System.Collections.ObjectModel.Collection
1.System.Collections.IList.get_Item(Int32 index) at System.Windows.Data.ListCollectionView.InternalItemAt(Int32 index) at System.Windows.Controls.VirtualizingStackPanel.CleanupContainers(Int32 firstViewport, ItemsControl itemsControl) at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(S开发者_开发技巧ize constraint) at Microsoft.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(Size constraint) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\Primitives\DataGridRowsPresenter.cs:line 109 at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.ContextLayoutManager.UpdateLayout() at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg) at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.TranslateAndDispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Application.RunInternal(Window window) at Apollo.App.Main() in F:\Workspaces\BVS\BVS\Apollo\Apollo\obj\Debug\App.g.cs:line 0
Any thoughts on what this could be from? Here is the oncollectionchanged code:
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
using (BlockReentrancy())
{
KeyValuePair<NotifyCollectionChangedEventHandler, CollectionChangedEventData>[] handlers = _collectionChangedHandlers.ToArray();
if (handlers.Length > 0)
{
foreach (KeyValuePair<NotifyCollectionChangedEventHandler, CollectionChangedEventData> kvp in handlers)
{
if (kvp.Value.Dispatcher == null)
{
kvp.Value.Action(e);
}
else
{
kvp.Value.Dispatcher.Invoke(kvp.Value.Action, DispatcherPriority.DataBind, e);
}
}
}
}
}
The top of that stacktrace suggest something going wrong in a normal List<>
in a ListCollectionView.
You probably should look at the code that binds to SelectedItem et al.
精彩评论