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

发布于 2024-12-05 19:52:12 字数 4334 浏览 4 评论 0原文

我正在另一个线程中添加到可观察集合,并且该集合绑定到 wpftoolkit 中的数据网格。

当此类事件发生时,oncollectionchanged 将通过主 gui 线程调用。

我看到的问题是大多数时候应用程序会抛出:

System.ArgumentOutOfRangeException 未处理 消息=索引超出范围。必须为非负数且小于集合的大小。 参数名称:索引 来源=mscorlib 参数名称=索引 堆栈跟踪: 在 System.ThrowHelper.ThrowArgumentOutOfRangeException() 在 System.Collections.Generic.List1.get_Item(Int32 索引) 在System.Collections.ObjectModel.Collection1.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 中的 Microsoft.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(大小约束):第 109 行 在 System.Windows.FrameworkElement.MeasureCore(Size availableSize) 在 System.Windows.UIElement.Measure(Size availableSize) 在 System.Windows.ContextLayoutManager.UpdateLayout() 在 System.Windows.ContextLayoutManager.UpdateLayoutCallback(对象 arg) 在 System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() 在 System.Windows.Media.MediaContext.RenderMessageHandlerCore(对象调整大小的CompositionTarget) 在 System.Windows.Media.MediaContext.RenderMessageHandler(对象调整大小的CompositionTarget) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象参数,布尔值 isSingleParameter) 在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象参数,布尔 isSingleParameter,委托 catchHandler) 在 System.Windows.Threading.DispatcherOperation.InvokeImpl() 在 System.Threading.ExecutionContext.runTryCode(对象 userData) 在System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode代码,CleanupCode backoutCode,对象userData) 在 System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback 回调,对象状态) 在 System.Windows.Threading.DispatcherOperation.Invoke() 在 System.Windows.Threading.Dispatcher.ProcessQueue() 在 System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd、Int32 msg、IntPtr wParam、IntPtr lParam、Boolean& 处理) 在MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,布尔值和处理) 在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(对象 o) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象参数,布尔值 isSingleParameter) 在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象参数,布尔 isSingleParameter,委托 catchHandler) 在 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority 优先级、TimeSpan 超时、委托方法、对象参数、布尔值 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(窗口窗口) 在 F:\Workspaces\BVS\BVS\Apollo\Apollo\obj\Debug\App.g.cs 中的 Apollo.App.Main():第 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);
                    }
                }
            }
        }

    }

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.List1.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(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

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

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往昔成烟 2024-12-12 19:52:12

该堆栈跟踪的顶部表明 ListCollectionView 中的正常 List 中出现了问题。

您可能应该查看绑定到 SelectedItem 等的代码。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文