WPF 已知问题 清空 CollectionView 的 SortDescriptions 可能抛出空异常
本文记录一个 WPF 的已知问题,在通过 CollectionViewSource 获取到 CollectionView 之后,如果 CollectionViewSource 对象已被 GC 回收,将可能在调用 CollectionView 的 SortDescriptions 属性进行清空或者移除项时,也就是使用 SortDescriptionCollection 类型的清空或者移除项时,在 WPF 框架里面抛出空异常
此问题已经报告给 WPF 官方,请看 https://github.com/dotnet/wpf/issues/7389
我现在是一个成熟的开发者了,自己报告的 BUG 就要自己修。此问题已修复,请看 https://github.com/dotnet/wpf/pull/7390
此问题的复现步骤如下
在一个 WPF 项目里面,构建出一个 CollectionViewSource 对象,接着只获取存放此 CollectionViewSource 对象的 View 属性,此 View 属性就是 CollectionView 类型的一个对象,将 CollectionView 存放到字段里面。等待 CollectionViewSource 被回收之后,调用 CollectionView 的 SortDescriptions 属性进行清空 SortDescriptionCollection 的内容。代码如下
public MainWindow()
{
InitializeComponent();
var collectionViewSource = new CollectionViewSource()
{
Source = new List<Foo>(),
IsLiveSortingRequested = true,
};
var collectionView = collectionViewSource.View;
_collectionView = collectionView;
collectionView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending));
Loaded += MainWindow_Loaded;
}
private readonly ICollectionView _collectionView;
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
GC.Collect();
GC.WaitForFullGCComplete();
GC.Collect();
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
_collectionView.SortDescriptions.Clear();
}
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin c7556d7b92605000011425f82793f9e4063e5a00
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin c7556d7b92605000011425f82793f9e4063e5a00
获取代码之后,进入 LechelaneHenayfucee 文件夹
运行代码,然后点击按钮,就可以看到在 WPF 框架里面抛出空异常
异常的调用堆栈大概如下
> PresentationFramework.dll!System.Windows.Data.ListCollectionView.PrepareLocalArray()
PresentationFramework.dll!System.Windows.Data.ListCollectionView.RefreshOverride()
PresentationFramework.dll!System.Windows.Data.CollectionView.RefreshInternal()
PresentationFramework.dll!System.Windows.Data.CollectionView.RefreshOrDefer()
PresentationFramework.dll!System.Windows.Data.ListCollectionView.SortDescriptionsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
WindowsBase.dll!System.ComponentModel.SortDescriptionCollection.RemoveItem(int index)
System.Private.CoreLib.dll!System.Collections.ObjectModel.Collection<System.ComponentModel.SortDescription>.RemoveAt(int index)
App.dll!MyClass.Foo();
阅读 WPF 框架的源代码,可以了解到原因就是因为 CollectionViewSource 对象没有被引用,从而被 GC 回收。在 CollectionViewSource 回收之后,将会让其 View 属性,也就是 CollectionView 类型,被 WPF 框架触发 DetachFromSourceCollection 方法进行回收。这个 DetachFromSourceCollection 方法代码如下
public virtual void DetachFromSourceCollection()
{
INotifyCollectionChanged incc = _sourceCollection as INotifyCollectionChanged;
if (incc != null)
{
IBindingList ibl;
if (!(this is BindingListCollectionView) ||
((ibl = _sourceCollection as IBindingList) != null && !ibl.SupportsChangeNotification))
{
incc.CollectionChanged -= new NotifyCollectionChangedEventHandler(OnCollectionChanged);
}
}
_sourceCollection = null;
}
在 DetachFromSourceCollection 方法里面,将 _sourceCollection 设置为空,这就导致了在清空 SortDescriptionCollection 内容的时候,尝试获取 _sourceCollection 的属性时,抛出空异常
WPF 已知问题 清空 CollectionView 的 SortDescriptions 可能抛出空异常的更多相关文章
- WPF的TextBox抛出InvalidOperationException异常:Cannot close undo unit because no opened unit exists.
近期遇到一个问题.应用使用过程中突然崩溃,查看dump发现异常信息例如以下: UI dispatcher has encountered a problem: 无法关闭撤消单元.由于不存在已打开的单元 ...
- Java知多少(49)throw:异常的抛出
到目前为止,你只是获取了被Java运行时系统抛出的异常.然而,程序可以用throw语句抛出明确的异常.Throw语句的通常形式如下: throw ThrowableInstance;这里,Thr ...
- WP8.1开发者预览版本号已知 Bug
偶的 Lumia 920 已经升级到最新的 8.1 开发者预览版本号,使用中没有发现什么问题. 可能是由于偶玩手机的情况比較少吧!忽然看到 MS 停止此版本号的更新,并说明有非常多的 BUG,偶就郁闷 ...
- HTML5地理定位(已知经纬度,计算两个坐标点之间的距离)
事实上,地球上任意两个坐标点在地平线上的距离并不是直线,而是球面的弧线. 下面介绍如何利用正矢公式计算已知经纬度数据的两个坐标点之间的距离.半正矢公式也成为Haversine公式,它最早时航海学中的重 ...
- 风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,
转自:http://www.cnblogs.com/ranranblog/p/5845010.html 风口之下,猪都能飞.当今中国股市牛市,真可谓“错过等七年”. 给你一个回顾历史的机会,已知一支股 ...
- Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转)
用我的方法来控制其他程序窗体上的窗口控件,必须先了解什么是 回调函数.我的理解是这样的: 回 调函数写出来不是自己的程序去调用的,反而是让其他的东西去调用,比如windows操作系统,比如其他的程序等 ...
- 对象布局已知时 C++ 对象指针的转换时地址调整
在我调试和研究 netscape 系浏览器插件开发时,注意到了这个问题.即,在对象布局已知(即对象之间具有继承关系)时,不同类型对象的指针进行转换(不管是隐式的从下向上转换,还是强制的从上到下转换)时 ...
- ARCgis已知线裁剪已知面
经常遇到需要在ArcGIS中,根据已知线图层(要素)切分已知面图层(要素).经过研究,利用topology拓扑菜单中的construct features可以实现.具体如下 现有用线图层A.面图层B, ...
- Java集合-5. (List)已知有一个Worker 类如下: 完成下面的要求 1) 创建一个List,在List 中增加三个工人,基本信息如下: 姓名 年龄 工资 zhang3 18 3000 li4 25 3500 wang5 22 3200 2) 在li4 之前插入一个工人,信息为:姓名:zhao6,年龄:24,工资3300 3) 删除wang5 的信息 4) 利用for 循
第六题 5. (List)已知有一个Worker 类如下: public class Worker { private int age; private String name; private do ...
- JAVA-集合作业-已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数
第二题 已知有十六支男子足球队参加2008 北京奥运会.写一个程序,把这16 支球队随机分为4 个组.采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚 ...
随机推荐
- SSR解决了什么问题?有做过SSR吗?你是怎么做的?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.是什么 Server-Side Rendering 我们称其为SSR,意为服务端渲染 指由服务侧完成页面的 HTML 结构拼接的页面处 ...
- 记录--uniapp自定义相机 自定义界面拍照录像闪光灯切换摄像头
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 因公司业务需要,需要开发水印相机功能,而项目代码用的uniapp框架,App端只能简单调用系统的相机,无法自定义界面,在此基础上,只能开发 ...
- vue前端项目中遇到的问题以及解决方案-不定时更新
1.vue-cli创建vue项目中全局使用mixin 首先需要安装插件 npm install style-resources-loader vue-cli-plugin-style-resource ...
- JS 为什么0==““ 会是true
0 是逻辑的 false 1 是逻辑的 true空字符串是逻辑的 false null 是逻辑的 false NaN==任何 都是false 所以:空字符串是逻辑的 false , 0是逻辑的fals ...
- 聊聊微信小程序的隐私协议开发
为什么需要隐私协议? 小程序隐私授权弹窗FAQ官方:https://developers.weixin.qq.com/community/develop/doc/00000ebac5c3e042384 ...
- 工具推荐-personal kanban
工具推荐 -- personal kanban 看板工具 在项目中接触到项目管理工具pingcode中含有看板工具 但是实际使用时一般一周才看一下项目进度 这个看板的参与度实际上很低 为了将日常的工作 ...
- Spark技术生态
Spark的技术生态 Spark的技术生态包含了各种丰富的组件,而不同的组件提供了不同功能,以适应不同场景. Spark core spark core包含Spark的基本功能,定义了RDD的API以 ...
- io_utils/time_utils
io_utils.h #pragma once #include<stdio.h> #include<stdarg.h> void PrintBinary(unsigned i ...
- 高抗干扰抗噪,段码LCD液晶低功耗驱动IC-VK2C23B,兼容市面上16C23
VK2C23是一个点阵式存储映射的LCD驱动器,可支持最大224点(56SEGx4COM)或者最大416点(52SEGx8COM)的LCD屏. 单片机可通过I2C接口配置显示参数和读写显示数据,也可通 ...
- 从bootstrap源码中学习Sass(一)
可以在github看代码,非常方便:https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss 就是有时候网络差. 基础用法 sc ...