我正將其添加到備用線程中的observablecollection,並將此集合綁定到wpftoolkit的datagrid。添加到具有備用線程的可觀察集合
當這種事件發生時,oncollectionchanged通過主gui線程調用。
我看到的問題是,大部分的時間應用程序將引發:
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(大小限制) 微軟。 Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(大小約束)在C:\ dd \ WPF_1 \ src \ wpf \ src \ ControlsPack \ WPFToolkit \ DataGrid \微軟\的Windows \控制\圖元\ DataGridRowsPresenter.cs:線109 在System.Windows.FrameworkElement.MeasureCore(尺寸availableSize) 在System.Windows.UIElement.Measure(尺寸availableSize) 在System.Windows.ContextLayoutManager.UpdateLayout( ) 在System.Windows.ContextLayoutManager.UpdateLayoutCallback(對象ARG) 在System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() 在System.Windows.Media.MediaContext.RenderMessageHandlerCore(對象resizedCompositionTarget) 在System.Windows.Media。 MediaContext.RenderMessageHandler(Object resizedCompositionTarget) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback,Object args,Boolean isSingleParameter) 在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的ExecutionContext,ContextCallback回調,對象狀態) 在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 &處理) 在MS.Win32.HwndWrapper.WndProc(IntPtr的HWND,MSG的Int32,IntPtr的wParam中,IntPtr的lParam的,布爾&處理) 在MS.Win32.HwndSubclass.DispatcherCallbackOperation(對象O) 在System.Windows.Threading程序。 ExceptionWrapper.InternalRealCall(代表回調,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優先級,TimeSpan超時,Delegate方法,Object args,Boolean isSingleParameter) 位於MS.Win32.HwndSubclass。SubclassWndProc(IntPtr的HWND,MSG的Int32,IntPtr的wParam中,IntPtr的LPARAM) 在MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG & MSG) 在System.Windows.Threading.Dispatcher.TranslateAndDispatchMessage(MSG & MSG) 在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
有關這可能來自何處的任何想法?這裏是oncollectionchanged代碼:
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);
}
}
}
}
}
爲什麼你自己正在處理(實現)CollectionChanged? –
是否有多個線程更新集合? ListCollectionView中的CollectionChanged處理程序將在收到通知後查看列表中的項目,並且它期望狀態與通知所告知的狀態相匹配。如果另一個線程在Invoke啓動後修改集合,則會使原始通知失效。 –
@HenkHolterman 這是因爲我們希望主線程上的collectionchanged事件觸發與在後臺運行的線程相關。 – Csharpfunbag