在我看来,WPF是一个设计得很美的产品。WPF解决了传统Win32 UI程序的四大局限:1) Win32的绘图是由各自Window元素独立控制,基于GDI的。WPF引入了
rendering thread来提高性能,优化算法,借用GPU加速。2) Win32依赖于GDI Object,在开发复杂窗口程序的时候,很容易就遭遇资源泄露和资源不足。比如早期的淘宝旺旺,开到几十个窗口的时候,程序就会出问题。所以淘宝针对这个问题,使用了统一控制台,合并多个窗口到标签页的方法来解决。而WPF只有最外面的窗口使用了Win32 Window和GDI,内部的元素都是抽象成了WPF自己的元素,不额外占用Win32 GDI资源的。3) Win32窗体程序严重依赖Windows Message模型。这要求程序员对系统知识有深入的了解。而且Win32 API并不是非常利于使用,比如要进行UI thread和Worker thread之间的通信,往往需要和SendMessage这样的API打交道。在WPF中,引入了Dispatcher类和Begin
Invoke方法,把这些复杂问题抽象了。加上CLR提供了更方便高效的开发环境,使用WPF是很愉快的工作。4) Win32缺乏数据,设计和代码三者之间的模式抽象。这三者在WPF中对应了数据绑定,XAML文件,以及后台代码。在WPF中可以更直观地使用各种模式比如MVC和MVVM。这些都体现了WPF设计上的优美。
再优美的东西都还是有局限性的。WPF的问题在于过多的模式和对CLR过度的依赖。了解WPF框架的人都知道,就一个简单的dependent property, 就把设计模式这本书里面的模式用掉一大半了。分析WPF框架代码的话,简直就是看一本设计模式的百科全书。我曾经统计过,关于mouse click这样一个event回调,WPF里面有7种不同的实现方法,分别各有好处,旨在解决不同问题。在这样高度灵活的背后,牺牲的是程序性能。无论是五花八门的模式,还是最常用的数据绑定,背后的主力都是CLR的reflection。过度依赖于reflection导致WPF程序规模一大,性能上就出问题。就算再怎么优化,也总找不到原生Win32程序那般流利的感觉。使用reflection也体现了对CLR的依赖。所以前面CLR的局限性,也适用于WPF。
语法标注解释 rendering 英音:['rendəriŋ] 表现;描写;渲染
invoke [] 唤起
reflection英音:[ri'flekʃən] 反射