WPF进阶之接口(2):IDisposable,ICollectionView
废话不多说,进入正题,先来说说IDisposable,看例子(来自MSDN): using System;
using System.ComponentModel; // 下面的例子将展示一个实施了IDisposable接口和Dispose方法的类 public class DisposeExample
{
public class MyResource: IDisposable
{
// 指针,指向非托管资源.
private IntPtr handle;
//类,托管资源.
private Component component = new Component();
// 标志,指示Dispose是否已被调用.
private bool disposed = false; // 构造函数.
public MyResource(IntPtr handle)
{
this.handle = handle;
} public void Dispose()
{
Dispose(true);
// 调用Dispose需要只是GC不要再调用Finalize().
GC.SuppressFinalize(this);
} private void Dispose(bool disposing)
{
// 检查是否已被调用过.
if(!this.disposed)
{
// 一个标志当在析构函数中,指示为false,别急后续将讲解原因.
if(disposing)
{
//Dispose托管资源.
component.Dispose();
} // 调用Kernel32函数释放非托管资源.
CloseHandle(handle);
handle = IntPtr.Zero; // 标记已经Dispose了.
disposed = true; }
} // ImportKernel32中的API,关于如何使用Interop我将在后续中讲解.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle); // 为了保持代码的可读性性和可维护性,千万不要在这里写释放非托管资源的代码
// 必须以Dispose(false)方式调用,以false告诉Dispose(bool disposing)函数是从垃圾回 // 收器在调用Finalize时调用的. ~MyResource()
{
Dispose(false);
}
}
public static void Main()
{
// 加入代码创建并使用MyResource对象. }
} 分析: 1.WPF中资源释放有哪几种方式?他们的内在关系? WPF中有两种释放资源的方法Dispose() 和 Finalize。 Dispose()由用户调用,Finalize()由GC调用。调用Dispose将释放托管和非托管资源,Finalize被GC调用时仅仅释放非托管资源。 当WPF程序较大时,程序员不能过分依赖GC,应该为各个自定义类实现IDisposable接口(如上例所示),并且在适当时候显示调用Diaposable方法。 2.IDisposable实施的要点 需要注意的有三点: 第一编写Dispose时要避免GC调用Finalize,重复销毁非托管资源。影响程序效率; 第二,在 Dispose(bool disposing)中需要分清层次,即是否已经dispose过( 通过disposed ),是否需要dispose托管资源; 第三,在析构函数中一定要Dispose(false)指示方法不要去dispose托管资源。因为在类析构的时候,GC将调用,用户不必再重复dispose托管资源,将此工作交给GC,这里注意一点,为什么在此时候,Finalize()以释放非托管资源,不禁止Dispose重复释放非托管资源。需要注意的是,Finalize一般只有默认实现,用户需要重写他才能实现具体非托管资源的释放,那么系统默认的Finalize()实际上没有作用。 一般实现自定义类的资源释dispose推荐使用实现IDisposable接口,这样可实现类托管和非托管资源dispose。 3. 进一步分析资源销毁的实质 使用Dispose() 和 Finalize都不能保证资源的立刻销毁,只是告诉GC这个资源我不用了,并加入GC的回收列表,当GC满足回收条件时,才会回收并销毁资源。那么如何知道GC的回收原理呢。请看后续章节。 ICollectionView接口 使用过ItemsControl控件的人都熟悉,可以将任意类型的变量集合赋值给ItemsSource属性,可以调用ItemsControl的方法实现集合成员的排序、分组、过滤、导航等功能。其实质是ICollectionView的功能。当一个集合赋值给ItemsSource属性后,ItemsControl自动给该集合包一层ICollectionView,并实现其方法。 具体实现请参看: 《WPF揭秘3》:Page 210--216 《CollectionView详解》 两篇文章都详细介绍如何重写ICollectionView 以实现 排序、分组、过滤、导航等功能。
http://hi.baidu.com/leo_han/item/900c44e03d8f08a9ce2d4f04 转自
WPF进阶之接口(2):IDisposable,ICollectionView的更多相关文章
- WPF进阶之接口(1):IValueConverter,IMultiValueConverter
看一个例子,FontFamily="Trebuchet MS, GlobalSansSerif.CompositeFont" .这样一条简单的语句,熟悉WPF的人在xaml中可能经 ...
- WPF进阶之接口(4):ICommand实现详解
上一章WPF进阶之接口():INotifyPropertyChanged,ICommand中我们遗留了几个问题,我将在本节中做出解释.在详细解释ICommand实现之前,我们现在关注一下什么是:弱引用 ...
- WPF进阶之接口(3):INotifyPropertyChanged,ICommand
INotifiPropertyChanged . 作用:向客户端发出某一属性值已更改的通知.该接口包含一个PropertyChanged事件成员(MSDN的解释) INotifyPropertyCha ...
- WPF使用IDataErrorInfo接口进行数据校验 - 简书
原文:WPF使用IDataErrorInfo接口进行数据校验 - 简书 class ValidationBindableBase : BindableBase, IDataErrorInfo { pu ...
- WPF进阶教程 - 使用Decorator自定义带三角形的边框
原文:WPF进阶教程 - 使用Decorator自定义带三角形的边框 写下来,备忘. Decorator,有装饰器.装饰品的意思,很容易让人联想到设计模式里面的装饰器模式.Decorator类负责包装 ...
- WPF进阶技巧和实战03-控件(3-文本控件及列表控件)
系列文章链接 WPF进阶技巧和实战01-小技巧 WPF进阶技巧和实战02-布局 WPF进阶技巧和实战03-控件(1-控件及内容控件) WPF进阶技巧和实战03-控件(2-特殊容器) WPF进阶技巧和实 ...
- WPF进阶技巧和实战03-控件(4-基于范围的控件及日期控件)
系列文章链接 WPF进阶技巧和实战01-小技巧 WPF进阶技巧和实战02-布局 WPF进阶技巧和实战03-控件(1-控件及内容控件) WPF进阶技巧和实战03-控件(2-特殊容器) WPF进阶技巧和实 ...
- wpf 属性变更通知接口 INotifyPropertyChanged
在wpf中将控件绑定到对象的属性时, 当对象的属性发生改变时必须通知控件作出相应的改变, 所以此对象需要实现 INotifyPropertyChanged 接口 例: //实现属性变更通知接口 INo ...
- WPF进阶技巧和实战07--自定义元素01
完善和扩展标准控件的方法: 样式:可使用样式方便地重用控件属性的集合,甚至可以使用触发器应用效果 内容控件:所有继承自ContentControl类的控件都支持嵌套的内容.使用内容控件,可以快速创建聚 ...
随机推荐
- 笔记本装ubuntu发热量大该如何缓解?
win7下的双卡技术是optimus, 驱动完善,不会让两个显卡同时满负荷工作, linux下由于驱动软件闭源, xorg的开源驱动没有做这个显卡电源管理, 目前的N卡较好解决方案就是bumblebe ...
- 心智图/思维导图(Mind Map/Mind Mapping),思维导图介绍
心智图(Mind Map),又称脑图.心智地图.脑力激荡图.思维导图.灵感触发图.概念地图.树状图.树枝图或思维地图,是一种图像式思维的工具以及一种利用图像式思考辅助工具来表达思维的工具. 心智图 ...
- Android中将一个图片切割成多个图片[转]
有种场景,我们想将一个图片切割成多个图片.比如我们在开发一个拼图的游戏,就首先要对图片进行切割. 以下是封装好的两个类,可以实现图片的切割.仅供参考和学习. 一个是ImagePiece类,此类保存了一 ...
- Oracle忘记密码找回
生活中,容易忘记Oracle数据库system用户的密码,怎么办呢,小生带你一步步重新登上Oracle ,及时你密码忘记了. 1.打开cmd窗口,输入 sqlplus / as sysdba 2.运行 ...
- Windows下Python添加库(模块)路径
动态的添加库路径.在程序运行过程中修改sys.path的值,添加自己的库路径 import syssys.path.append(r'your_path') 在Python安装目录下的\Lib\sit ...
- C++求两个数的最大值
//不使用if,:?等推断语句.求两个数字中最大的那个数字. #include<iostream> using namespace std; int main() { int a = -1 ...
- Mysql 修改数据库,mysql修改表类型,Mysql增加表字段,Mysql删除表字段,Mysql修改字段名,Mysql修改字段排列顺序,Mysql修改表名
对于已经创建好的表,尤其是已经有大量数据的表,如果需要对表做一些结构上的改变,我们可以先将表删除(drop),然后再按照新的表定义重建表.这样做没有问题,但是必然要做一些额外的工作,比如数据的重新加载 ...
- xdebug远程调试原理分析
xdebug可以控制PHP程序的执行,这意味着xdebug可以在任何时候暂停或者恢复正在运行的PHP程序.当PHP程序被暂停的时候,xdebug可以获取到程序的有关 信息,比如变量的值等.xdebug ...
- 开发avr单片机网络资源
1.avr用的c语言标准库 http://www.nongnu.org/avr-libc/ 2.avr的下载上传器 http://www.nongnu.org/avrdude/ 3.编程环境platf ...
- C++不让程序一闪而过
末尾加上System("pause") 不过需要注意,这个只在win32下有效.不具备可移植性.