在非UI线程创建WPF SolidColorBrush引发异常却未给出正确提示
非UI线程创建SolidColorBrush未触发预期异常的原因
核心原因:WPF线程检查的延迟性
WPF并非对所有UI相关对象的跨线程创建都即时抛出异常,像SolidColorBrush这类Freezable派生类,其线程合法性检查是延迟到实际参与UI渲染、布局或数据绑定操作时才执行的,而非对象实例化的瞬间。
当你在非UI线程创建该Brush并应用到DataGridCell的Style Setter后,Brush本身不会立刻触发线程错误,直到DataGrid启动虚拟化布局流程(对应调用栈中的DataGridCellsPanel.VirtualizeChildren),此时系统尝试访问内部集合MultipleCopiesCollection的元素时,因Brush的线程上下文非法导致集合状态异常,最终抛出ArgumentOutOfRangeException——这属于跨线程操作引发的次生异常,而非直接的跨线程访问提示。
插件环境的特殊影响
在Outlook/VSTO插件场景中,由于部分UI操作由Outlook的消息循环驱动,导致SynchronizationContext.Current为null,await后的代码会默认运行在线程池线程上。此时创建的SolidColorBrush没有关联到WPF UI线程的Dispatcher,WPF的初始线程验证机制无法识别到非法操作,直到后续布局流程中访问该对象的内部依赖状态,才会触发间接的集合访问异常。
异常调用栈
System.Windows.Controls.MultipleCopiesCollection.get_Item(Int32 index) System.Windows.Data.ListCollectionView.InternalItemAt(Int32 index) System.Windows.Data.ListCollectionView.GetItemAt(Int32 index) System.Windows.Controls.ItemCollection.GetItemAt(Int32 index) System.Windows.Controls.DataGridCellsPanel.VirtualizeChildren(List1 blockList, IItemContainerGenerator generator) System.Windows.Controls.DataGridCellsPanel.GenerateAndMeasureChildrenForRealizedColumns(Size constraint) System.Windows.Controls.DataGridCellsPanel.MeasureOverride(Size constraint) System.Windows.FrameworkElement.MeasureCore(Size availableSize) System.Windows.UIElement.Measure(Size availableSize) MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint) System.Windows.Controls.ItemsPresenter.MeasureOverride(Size constraint) System.Windows.FrameworkElement.MeasureCore(Size availableSize) [... 更多FrameworkElement/Measure调用栈]
内容的提问来源于stack exchange,提问作者Lumo
相关产品推荐
相关产品推荐

