使用备用线程添加到可观察的集合

问题描述:

我在备用线程中添加了一个observablecollection,并且该集合绑定到了wpftoolkit中的datagrid.

I am adding to an observablecollection in an alternate thread and this collection is bound to a datagrid from the wpftoolkit.

此类事件发生时,oncollectionchanged正在通过主gui线程调用.

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未处理 消息=索引超出范围.必须为非负数并且小于集合的大小. 参数名称:索引 来源= mscorlib ParamName =索引 堆栈跟踪: 在System.ThrowHelper.ThrowArgumentOutOfRangeException() 在System.Collections.Generic.List 1.get_Item(Int32 index) at System.Collections.ObjectModel.Collection 1.System.Collections.IList.get_Item(Int32索引)处 在System.Windows.Data.ListCollectionView.InternalItemAt(Int32索引) 在System.Windows.Controls.VirtualizingStackPanel.CleanupContainers(Int32 firstViewport,ItemsControl itemsControl)中 在System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(大小约束) 在C. \ dd \ WPF_1 \ src \ wpf \ src \ ControlsPack \ WPFToolkit \ DataGrid \ Microsoft \ Windows \ Controls \ Primitives \ DataGridRowsPresenter.cs:line 109处的Microsoft.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(大小约束) 在System.Windows.FrameworkElement.MeasureCore(Size availableSize) 在System.Windows.UIElement.Measure(Size availableSize) 在System.Windows.ContextLayoutManager.UpdateLayout() 在System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg) 在System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() 在System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) 在System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) 在System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate回调,Object args,Boolean isSingleParameter) 在System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象参数,布尔值isSingleParameter,委托catchHandler) 在System.Windows.Threading.DispatcherOperation.InvokeImpl() 在System.Threading.ExecutionContext.runTryCode(Object userData) 在System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode代码,CleanupCode backoutCode,对象userData) 在System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态) 在System.Windows.Threading.DispatcherOperation.Invoke() 在System.Windows.Threading.Dispatcher.ProcessQueue() 在System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,布尔值和已处理) 在MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean&处理) 在MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 在System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate回调,Object args,Boolean isSingleParameter) 在System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象参数,布尔值isSingleParameter,委托catchHandler) 在System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority优先级,TimeSpan超时,Delegate方法,对象args,布尔isSingleParameter) 在MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam) 在MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 在System.Windows.Threading.Dispatcher.TranslateAndDispatchMessage(MSG& msg) 在System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame框架) 在System.Windows.Application.RunInternal(Window窗口) 在F:\ Workspaces \ BVS \ BVS \ Apollo \ Apollo \ obj \ Debug \ App.g.cs:line 0中的Apollo.App.Main()处

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.List1.get_Item(Int32 index) at System.Collections.ObjectModel.Collection1.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(Size 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

对这可能是什么有任何想法吗?这是oncollection更改的代码:

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);
                    }
                }
            }
        }

    }

该堆栈跟踪的顶部表明在ListCollectionView的普通List<>中有问题.

The top of that stacktrace suggest something going wrong in a normal List<> in a ListCollectionView.

您可能应该看一下绑定到SelectedItem等的代码.

You probably should look at the code that binds to SelectedItem et al.