GDI+的雷区

GDI+的雷区

 2005-4-22

 

 

千呼万唤之中,微软终于推出了早该有的精心设计的下一代图形程序接口GDI+,并成为dotNet的图形绘制核心,这些也可以算是陈年旧事了。当几批给微软趟雷的勇士倒下后,大家开始发现GDI+实为鸡肋,食之无味,弃之可惜。

 

雷区:贼慢的速度

 

诸位应该也有很多人都已经注意到了,不是一般的慢。找微软和MVP给的优化方法都没用,根本原因有两个,一个是GDI+目前不使用硬件加速,准确的说它基于GDI的部分是通过GDI加速的,其他的部分是纯CPU计算;二是算法实现有问题,如典型的画位图的问题,绘制的速度和源位图大小有关,注意不是和实际绘制的部分的大小有关,而是和源位图的总大小有关。就是说绘制128x128的位图和绘制1024x1024的位图的一个128x128的部分,这两种方法都只画128x128,但速度有天壤之别,这个问题在好多论坛都讨论过,大家都不能理解不能接受,只好去用GDI。不要以为这是没有使用MSDN和那些MVP的优化建议,不相信的可以自己试试。

 

雷区:失败的封装

 

dotNet最好的地方是提供了一套设计优秀、风格统一的API,但GDI+的封装部分,就是System.Drawing名字空间里的东西,却做得很失败。dotNet的核心优势是垃圾收集,对纯内存数据对象,是不需要操心其生存期管理的,不但简化了内存管理,而且使必须为函数的返回值分配内存的糟糕的API接口成为过去,可以既提供直观易用又没有性能损失的函数。按着垃圾收集模式的精神,是应该鼓励不需要Dispose的对象的。但Sytem.Drawing名字空间里的类几乎全部需要Dispose,连MatrixStringFormat这种东西都要Dispose。纠其原因,就是这些类没有提供dotNet的实现,而是包装的GDI+对象的指针,这种方式节省了他们开发的时间,却给了我们无尽的麻烦,而且处于兼容性考虑,以后的版本也很难将那个IDisposable接口从那些类上去掉。

 

而更糟的是微软的样例代码里都不掉用Dispose,这样代码看起来很清晰简洁,却要一群MVP四处劝说一定要Dispose。知道了它的内部实现,每个程序员都会认为它确实应该被尽快Dispose,而不能等垃圾收集去做,因为垃圾收集器是不知道这些非托管资源占了多少内存、占了多少系统资源的。写dotNet控件的程序员经常遇到IDE变慢甚至报告资源不足的情况,就是有太多的GDI+对象没释放的关系。而MSDN可没有教人Dispose啊,连Bitmap对象都没!

 

知道了应该Dispose,那么就Dispose呗。

Pen blackPen = new Pen(Color.Black, 3);

e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);

blackPen.Dispose();

这行了吧,不行!DrawLine可能抛异常啊,那样blackPen还是没有释放,所以要

Pen blackPen = null;

Try {

       blackPen = new Pen(Color.Black, 3);

e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);

}

finally {

blackPen.Dispose();

}

幸亏C#里提供了uisng,可以简化为

using (blackPen = new Pen(Color.Black, 3)) {

e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);

}

可是一个GDI+对象还好,10个怎么办,在绘图程序里可不止这几个啊,难道using (…) using (…) using (…) using (…) …??这代码还能读吗?

 

于是大家也只能破罐破摔,小东西就不管了。

 

雷区3:和交互效率不高

 

由于速度问题,大家只能求救于GDI,想那GDI+提供了不少和GDI交互的函数,就像早就知道大家有这么一天似的。可一用就不对了,因为大部分情况下它是拷贝一份生成GDI对象,GDI操作完再拷贝回来。真是让人预哭无泪。

 

雷区4:又提供新的基于加速的图形,还要做什么?

 

正如Joel所说,微软现在不停的出各种各样的新的API,又在不久之后做出新的替代品而放弃旧的,对程序员来说就是恶梦。旧问题不解决,而用新的替代,然后新的又带来一堆新问题,然后再出更新的来替代。如果不是必要,不要在GDI+上下太大的赌注。

 

结论

 

当然,天下没有完美的东西,虽然有很多缺陷,GDI+的功能还是非常有吸引力,要求不高的话还是很有用的。这里给大家提供了GDI+的几大雷区,希望大家不要都在趟雷中牺牲了。

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值