UI 元素添加到控件集合时抛出异常

Posted

技术标签:

【中文标题】UI 元素添加到控件集合时抛出异常【英文标题】:UI Element throws exception when added to control-collection 【发布时间】:2014-03-30 15:43:25 【问题描述】:

我正在尝试在另一个线程中为我的应用程序加载我的插件。该过程非常耗时,并且应用程序在启动时会冻结很长时间。系统工作如下:

xml 文件定义应添加到 UI 的控件和类型。一个类现在读取 XML 并创建控件。这些是通过 Invoking 创建的(使用主 UI-Thread 的 Dispatcher)。

在这种情况下,我正在创建一个 RibbonTabItem(来自 Codeplex 的 Fluent Ribbon)。一切正常,直到我将此控件添加到功能区本身。即使通过调度程序调用也会发生这种情况。但只要这条线被调用:

RibbonTabItem i = item;
uiDispatcher.Invoke(() => this._ribbon.Tabs.Add(i));

我得到这个异常堆栈跟踪:

在 System.Windows.Freezable.EnsureConsistentDispatchers(DependencyObject 所有者,DependencyObject 子级) 在 System.Windows.Freezable.OnFreezablePropertyChanged(DependencyObject oldValue,DependencyObject newValue,DependencyProperty 属性) 在 System.Windows.Media.RenderData.PropagateChangedHandler(EventHandler 处理程序,布尔添加) 在 System.Windows.UIElement.RenderClose(IDrawingContent 新内容) 在 System.Windows.Media.VisualDrawingContext.CloseCore(RenderData 渲染数据) 在 System.Windows.Media.RenderDataDrawingContext.DisposeCore() 在 System.Windows.Media.DrawingContext.System.IDisposable.Dispose() 在 System.Windows.Media.RenderDataDrawingContext.Close() 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 MS.Internal.Helper.ArrangeElementWithSingleChild(UIElement 元素,大小排列尺寸) 在 System.Windows.Controls.ContentPresenter.ArrangeOverride(大小排列大小) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Border.ArrangeOverride(大小 finalSize) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Control.ArrangeOverride(大小排列边界) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Border.ArrangeOverride(大小 finalSize) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Grid.ArrangeOverride(大小排列大小) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Control.ArrangeOverride(大小排列边界) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 Fluent.RibbonTabsContainer.ArrangeOverride(Size finalSize) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.ScrollContentPresenter.ArrangeOverride(大小排列大小) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Grid.ArrangeOverride(大小排列大小) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.Control.ArrangeOverride(大小排列边界) 在 System.Windows.Controls.ScrollViewer.ArrangeOverride(大小排列大小) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.Controls.DockPanel.ArrangeOverride(大小排列大小) 在 System.Windows.FrameworkElement.ArrangeCore(矩形 finalRect) 在 System.Windows.UIElement.Arrange(矩形 finalRect) 在 System.Windows.ContextLayoutManager.UpdateLayout() 在 System.Windows.UIElement.UpdateLayout() 在 Fluent.RibbonTabControl.UpdateSelectedContent() 在 Fluent.RibbonTabControl.OnSelectionChanged(SelectionChangedEventArgs e) 在 System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(列表1 unselectedInfos, List1 selectedInfos) 在 System.Windows.Controls.Primitives.Selector.SelectionChanger.End() 在 System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(ItemInfo 信息,布尔假设 InItemsCollection) 在 System.Windows.Controls.Primitives.Selector.OnSelectedIndexChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs 参数) 在 System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex、DependencyProperty dp、PropertyMetadata 元数据、EffectiveValueEntry oldEntry、EffectiveValueEntry& newEntry、Boolean coerceWithDeferredReference、Boolean coerceWithCurrentValue、OperationType operationType) 在 System.Windows.DependencyObject.CoerceValue(DependencyProperty dp) 在 System.Windows.Controls.Primitives.Selector.OnItemsChanged(NotifyCollectionChangedEventArgs e) 在 Fluent.RibbonTabControl.OnItemsChanged(NotifyCollectionChangedEventArgs e) 在 System.Windows.Controls.ItemsControl.OnItemCollectionChanged2(对象发送者,NotifyCollectionChangedEventArgs e) 在 System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(对象发送者,NotifyCollectionChangedEventArgs e) 在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs 参数) 在 System.Windows.Controls.ItemCollection.OnViewCollectionChanged(对象发送者,NotifyCollectionChangedEventArgs e) 在 System.Windows.WeakEventManager.ListenerList1.DeliverEvent(Object sender, EventArgs e, Type managerType) at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args) at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at MS.Internal.Controls.InnerItemCollectionView.Insert(Int32 index, Object item) at System.Windows.Controls.ItemCollection.Insert(Int32 insertIndex, Object insertItem) at Fluent.Ribbon.OnTabsCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) 在 System.Collections.ObjectModel.ObservableCollection1.InsertItem(Int32 index, T item) at System.Collections.ObjectModel.Collection1.Add(T 项目) 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.GUI\MenuSystem\RibbonUIHost 中的 FGCore.GUI.MenuSystem.RibbonUIHost.c_DisplayClass12.b_4()。 CS:第 77 行 在 System.Windows.Threading.Dispatcher.Invoke(操作回调、DispatcherPriority 优先级、CancellationToken cancelToken、TimeSpan 超时) 在 System.Windows.Threading.Dispatcher.Invoke(操作回调) 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.GUI\MenuSystem\RibbonUIHost.cs:line 77 中的 FGCore.GUI.MenuSystem.RibbonUIHost.SortHulls() 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.GUI\MenuSystem\UIHost.cs 中的 FGCore.GUI.MenuSystem.UIHost.Add(String id, FrameworkElement element, Int32 order, PropertiesCollection meta):第 54 行 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\Integrity\IntegrationPipeline 中的 FGCore.Addin.Integrity.IntegrationPipeline.c_DisplayClass1a.b_13()。 CS:第 486 行 在 System.Windows.Threading.DispatcherOperation.InvokeDelegateCore() 在 System.Windows.Threading.DispatcherOperation.InvokeImpl() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 System.Windows.Threading.DispatcherOperation.Wait(时间跨度超时) 在 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation 操作,CancellationToken cancelToken,TimeSpan 超时) 在 System.Windows.Threading.Dispatcher.Invoke(操作回调、DispatcherPriority 优先级、CancellationToken cancelToken、TimeSpan 超时) 在 System.Windows.Threading.Dispatcher.Invoke(操作回调) 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\Integrity\IntegrationPipeline 中的 FGCore.Addin.Integrity.IntegrationPipeline.ExtendHost(XmlElement subControl, UIHost host, IntegrationDescription desc, String path, Boolean creativeMode) .cs:第 486 行 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\Integrity\IntegrationPipeline.cs: 392 中的 FGCore.Addin.Integrity.IntegrationPipeline.ExtendRibbonHost(XmlElement hostNode, IntegrationDescription desc) 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\Integrity\IntegrationPipeline.cs: 359 中的 FGCore.Addin.Integrity.IntegrationPipeline.ProcessExtensibility(IntegrationDescription 描述) 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\AddinProvider.cs: 348 行中的 FGCore.Addin.AddinProvider.RunAddin(Guid id,SettingsFile 注册表) 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\AddinProvider.cs:line 313 中的 FGCore.Addin.AddinProvider.RunAddins() 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\Core\FGCore.Addin\AddinCore.cs:line 91 中的 FGCore.Addin.AddinCore.RunAddins() 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\ProjectFlowerGrid.ApplicationBase\IDE.cs:line 253 中的 ProjectFlowerGrid.IDE.b_1() 在 System.Threading.Tasks.Task.InnerInvoke() 在 System.Threading.Tasks.Task.Execute() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.GetResult() 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\ProjectFlowerGrid.ApplicationBase\IDE.cs:line 253 中的 ProjectFlowerGrid.IDE.d_2.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__0(对象状态) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象 args,Int32 numArgs) 在 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象源,委托方法,对象 args,Int32 numArgs,委托 catchHandler) 在 System.Windows.Threading.DispatcherOperation.InvokeImpl() 在 System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(对象状态) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext 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,Boolean& 处理) 在 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean& 处理) 在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(对象 o) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象 args,Int32 numArgs) 在 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象源,委托方法,对象 args,Int32 numArgs,委托 catchHandler) 在 System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority 优先级,TimeSpan 超时,委托方法,对象 args,Int32 numArgs) 在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32 味精,IntPtr wParam,IntPtr lParam) 在 MS.Win32.UnsafeNativeMethods.DispatchMessage(味精和味精) 在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 框架) 在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame 框架) 在 System.Windows.Threading.Dispatcher.Run() 在 System.Windows.Application.RunDispatcher(对象忽略) 在 System.Windows.Application.RunInternal(窗口窗口) 在 System.Windows.Application.Run(窗口窗口) 在 System.Windows.Application.Run() 在 d:\Sicherung\Visual Studio\Workspace\ProjectFlowerGrid\src\ProjectFlowerGrid.ApplicationBase\obj\Debug\App.g.cs:line 50 中的 ProjectFlowerGrid.App.Main() 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart()

我已经读到这可能是由在一个线程中创建并在另一个线程中使用的资源(如画笔)引起的。很有道理。但我真的不知道如何解决这个问题。如果我必须冻结所有资源,我怎么能不为每个 Freezable 手动执行此操作?

还有其他想法吗?

谢谢:)

【问题讨论】:

【参考方案1】:

请原谅这个可悲的错误。我忽略了我真的在并行线程中创建了可冻结的资源。那是一些刷子。我只是没有看到代码,因为它只是这个庞大类的一小部分。

我将它包装到 UI 调度程序的调用中,现在不再有异常。

再次抱歉。我写这个有点快。不会再发生了。

【讨论】:

以上是关于UI 元素添加到控件集合时抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

视图设置为 inputAccessoryView 在添加回普通视图时抛出异常

WPF DatePicker 更改月份时抛出异常

VS2015 在添加新的实体数据模型时抛出异常

new ActiveXObject("Scripting.FileSystemObject") 时抛出异常 .

如何避免在迭代集合为 null 时抛出的空引用异常?

Windows Azure:“已添加具有相同密钥的项目。”选择时抛出异常