1.DisptcherObject提供了线程和并发模型,实现了消息系统。

2.DependencyObject提供了更改通知,实现了绑定,样式。
3.Visual是托管API和非托管API(milcore)的之间的关键点。
4.UIElement定义了Layout,Input和Events等核心子系统。Measure让一个组件来决定自己想要的size,而Arrange让父组件放置子组件并决定子组件的最终size。
5.WPF的外观和行为总共有3个模型:数据模型(Properties),交互模型(Commands,Events),显示模型(Template)。
6.不同应用程序域间的WPF可以通过INativeHandleContract来实现WPF AddIn。
7.WPF定义了三个呈现曾:
     
  • 呈现层 0 无图形硬件加速。 所有图形功能都使用软件加速。 DirectX 版本级别低于 9.0。

  • 呈现层 1 某些图形功能使用图形硬件加速。 DirectX 版本级别高于或等于 9.0。

  • 呈现层 2 大多数图形功能都使用图形硬件加速。 DirectX 版本级别高于或等于 9.0。

8. WPF性能提升: 
     1)布局处理过程。
          再次调用布局处理的几个操作:向集合中添加了一个子对象; 向子对象应用了 LayoutTransform;为子对象调用了 UpdateLayout 方法; 用影响测量或排列过程的元数据进行了标记的依赖项属性的值发生更改。
          提高方法:
               尽量使用最有效的Panel,功能越强大的Panel性能成本也就越高; 
               更新而不替换RenderTransform; 
               从上到下生成逻辑树。
     2)二维图形和图像处理
          提高方法:
                Drawing对象比Shape对象结构简单,性能更为优越,但是不是从FrameworkElement集成,使用时注意; 
                使用StreamGeometry而不是PathGeometry;
                如果需要显示缩略图,尽量使用小版本的图像,或者请求WPF将图像解码为缩略图大小,或者请求WPF加载缩略图大小。始终将图像解码为所需的大小而不是默认大小。
                
     3)行为
          提高方法:
               注册DependencyObject时,尽量提供默认值和PropertyMetadata,而不是放在以后赋值。
               冻结Freezable会改善程序性能,不再需要因维护更改通知而消耗资源。
               使用VirtualizingStackPanel而不是StackPanel,注意:这样子资源苏不可见时即被移除,这时无法访问不可见的子元素。
               尽可能使用静态资源,只在必须得情况下使用动态资源。
               避免在FlowDocument使用TextBlock,而应该使用Run。
               避免在TextBlock里使用Run来设置文本属性。
               避免执行到Lable.Content属性的数据绑定。 如果数据源频繁更新,应用TextBlock.Text替换。 
     4)数据绑定
          提高方法:
                性能从高到低:DependencyObject 〉INotifyPropertyChanged  
                如果绑定到较大的CLR对象,考虑将对象拆分成多个具有少量属性的CLR对象
                将IList(而非IEnumerable)绑定到ItemsCount
     5)控件
          提高方法:
               设置 IsVirtualizing 为true, VirtualizationMode 为Recycling,  IsDeferredScrollingEnabled为true。
                    IsVirtualizing代表是否UI虚拟化,当设置为true时,表示只有当数据项在屏幕上可见时才会在内存中创建存储。 
                    VirtualizationMode代表是否容器回收,正常情况下ItemsControl会为滚动到视图中的每个item创建项容器,并销毁滚动到视图之外的每个item的项容器。通过Recycling,可以让控件能够将现有项容器重复利用于不同的数据项。
                    
                    IsDeferredScrollingEnabled代表是否延长滚动,正常情况下当用户拖到滚动条上的滑块时,内容视图会不会不断更新。当设置为true, 表示只有当用户松开滚动条时,内容才会更新。
                    
     6)其他
               尽量使用画笔的不透明度(Opacity),而不是使用元素的Opacity,修改元素的Opacity会导致WPF创建临时图标。
               配置“WPF字体缓存服务”从手动为自动(延迟启动),这个服务如果没有启动,会随着第一个WPF程序启动时启动。这样导致第一个WPF的初始化事件很长。
9. WPF线程模型
    典型的wpf程序有2个线程,一个用于负责渲染,一个用于管理UI。UI线程把工作项排序到Dispatcher对象中,Dispatcher对象根据工作项的优先级选择执行,直到全部执行。每个UI线程必须至少有一个Dispatcher,每个Dispatcher必须在一个线程里工作。 
     可以通过CheckAccess来判断线程是否可以访问DispatcherObject。原理是:大多数类继承于DispatcherObject,DispatcherObject在构造时把当前运行线程的Dispatcher引用存储。当访问DispatcherObject时,检查当前线程关联的Dispatcher于构造中存储的Dispatcher进行比较,如果相同返回True,不同返回False。
     要构建响应速度快、且用户友好的应用程序,诀窍是减小工作项,以最大限度地提高 Dispatcher 吞吐量。 这样,工作项将永远不会因为在 Dispatcher 队列中等待处理而失效。 输入与响应之间的任何可察觉的延迟都会使用户不快。
     嵌套的消息泵:比如MessageBox,我们调用show后需要用户单击“OK"才能返回。MessageBox创建的窗口必须要由一个消息泵才能进行交互。我们在等待用户单击”OK“时原始应用程序窗口不响应用户输入。
     具体实现: WPF使用一种嵌套的消息处理系统, Dispatcher类包含一个PushFrame的特殊方法, 该方法存储应用程序的当前执行点,然后开始一个新的消息泵,当嵌套的消息泵执行结束时,执行将在最初的PushFrame调用之后继续。PushFrame内部实现类似Win32中GetMessage、TranslateMessage、DispatchMessage的消息泵。 (通过这个原理,我们可以实现自己的MessageBox系统)
     Application.Run内部调用Dispatcher.Run(),Dispatcher.Run()内部调用了Dispatcher.PushFrame(..), 实现了一个Win32的消息泵。
     DispatcherOperation对象用于与Dispatcher队列上的Delegate进行交互,例如更改委托的优先级、从事件队列中移除委托、等待委托返回、获取委托执行之后返回的值。
     Application.DoEvents方法:处理当前Dispatcher消息队列里的所有windows消息。
     
     关于BeginInvoke和Invoke,向关联的Dispatcher的队列中插入同步或者异步工作项。
10.Weak Event Pattern
     传统的侦听事件可能导致内存泄漏,source.SomeEvent += new SomeEventHandler(MyEventHandler) 。这是因为为事件源添加事件处理程序时,会创建一个事件源到事件侦听器(所谓事件侦听器,就是Delegate对象)的强引用。这样事件侦听器就会有生命周期,该生命周期和事件源的生命周期有关, 除非显式的移除了事件处理程序, source.SomeEvent -= new SomeEventHandler(MyEventHandler) 。当事件源从可视树中移除时,事件侦听器还是有生命周期,但此时事件处理程序不会被调用,也就是说造成了无用的事件侦听器的还一直存在。这种情况下就需要弱事件模式。
     实现弱事件模式,有三种方式:使用系统已有的(CollectionChangedEventManager,PropertyChangedEventManager等等); 使用泛型弱事件管理器(WeakEventManager<TEventSource, TeventArgs>, 注意有性能损失); 继承WeakEventManager类,实现自定义弱事件管理器。
     例如: 
                    class SomeEventWeakEventManager : WeakEventManager
{
    private SomeEventWeakEventManager()
    {
    }
    /// <summary>
    /// Add a handler for the given source's event.
    /// </summary>
    public static void AddHandler(EventSource source, 
                                  EventHandler<SomeEventEventArgs> handler)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (handler == null)
            throw new ArgumentNullException("handler");
        CurrentManager.ProtectedAddHandler(source, handler);
    }
    /// <summary>
    /// Remove a handler for the given source's event.
    /// </summary>
    public static void RemoveHandler(EventSource source, 
                                     EventHandler<SomeEventEventArgs> handler)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (handler == null)
            throw new ArgumentNullException("handler");
        CurrentManager.ProtectedRemoveHandler(source, handler);
    }
    /// <summary>
    /// Get the event manager for the current thread.
    /// </summary>
    private static SomeEventWeakEventManager CurrentManager
    {
        get
        {
            Type managerType = typeof(SomeEventWeakEventManager);
            SomeEventWeakEventManager manager = 
                (SomeEventWeakEventManager)GetCurrentManager(managerType);
            // at first use, create and register a new manager
            if (manager == null)
            {
                manager = new SomeEventWeakEventManager();
                SetCurrentManager(managerType, manager);
            }
            return manager;
        }
    }
    /// <summary>
    /// Return a new list to hold listeners to the event.
    /// </summary>
    protected override ListenerList NewListenerList()
    {
        return new ListenerList<SomeEventEventArgs>();
    }
    /// <summary>
    /// Listen to the given source for the event.
    /// </summary>
    protected override void StartListening(object source)
    {
        EventSource typedSource = (EventSource)source;
        typedSource.SomeEvent += new EventHandler<SomeEventEventArgs>(OnSomeEvent);
    }
    /// <summary>
    /// Stop listening to the given source for the event.
    /// </summary>
    protected override void StopListening(object source)
    {
        EventSource typedSource = (EventSource)source;
        typedSource.SomeEvent -= new EventHandler<SomeEventEventArgs>(OnSomeEvent);
    }
    /// <summary>
    /// Event handler for the SomeEvent event.
    /// </summary>
    void OnSomeEvent(object sender, SomeEventEventArgs e)
    {
        DeliverEvent(sender, e);
    }
}
     使用方法: 
            将
                   source.SomeEvent += new SomeEventEventHandler(OnSomeEvent);
                   source.SomeEvent -= new SomeEventEventHandler(OnSome);
            替换为  
                    SomeEventWeakEventManager.AddHandler(source, OnSomeEvent);
                    SomeEventWeakEventManager.RemoveHandler(source, OnSomeEvent);

          http://msdn.microsoft.com/zh-cn/library/aa970683.aspx   优化WPF应用程序性能
          http://msdn.microsoft.com/en-us/library/ms741870.aspx   WPF线程模型

WPF架构分析的更多相关文章

  1. 【WPF系列】基础学习-WPF架构概览

    引言 WPF从.net framewok3.0加入以来,经历了很多跟新.每次更新都给用户带来了新的功能或者优化性能.下面我们首先看下WPF再.netFramework中的位置,接着介绍下WPF的架构框 ...

  2. tomcat架构分析 (Session管理)

    Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是获取一个session,然后向session中存取数据,然后再销毁session.那么如何产生se ...

  3. Magento架构分析,Magento MVC 设计分析

    Magento架构分析,Magento MVC 设计分析 分类:Magento 标签:Magento MVC.Magento架构 669人浏览 Magento 采用类似 JAVA的架构,其扩展与稳定性 ...

  4. Flickr 网站架构分析

    Flickr 网站架构分析 Flickr.com 是网上最受欢迎的照片共享网站之一,还记得那位给Windows Vista拍摄壁纸的Hamad Darwish吗?他就是将照片上传到Flickr,后而被 ...

  5. Android架构分析之Android消息处理机制(二)

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在上一篇文章中我们看了一个使用Handler处理Message消息的样例,本文我们 ...

  6. NopCommerce架构分析(转载)

    原文 一,NopCommerce架构分析之开篇 NopCommerce是.net开源项目中比较成熟的一款业务应用框架,也是电子商务系统中的典范.所以很想多学习一下里面的设计和实现方式. 二,NopCo ...

  7. Qualcomm Android display架构分析

    Android display架构分析(一) http://blog.csdn.net/BonderWu/archive/2010/08/12/5805961.aspx http://hi.baidu ...

  8. tomcat架构分析-索引

    出处:http://gearever.iteye.com tomcat架构分析 (概览) tomcat架构分析 (容器类) tomcat架构分析 (valve机制) tomcat架构分析 (valve ...

  9. [转载] 关于“淘宝应对"双11"的技术架构分析”

    微博上一篇最新的关于“淘宝应对"双11"的技术架构分析”.数据产品的一个最大特点是数据的非实时写入.

随机推荐

  1. 自制小工具大大加速MySQL SQL语句优化(附源码)

    引言 优化SQL,是DBA常见的工作之一.如何高效.快速地优化一条语句,是每个DBA经常要面对的一个问题.在日常的优化工作中,我发现有很多操作是在优化过程中必不可少的步骤.然而这些步骤重复性的执行,又 ...

  2. oracle中视图v$sql的用途

    1.获取正在执行的sql语句.sql语句的执行时间.sql语句的等待事件: select a.sql_text,b.status,b.last_call_et,b.machine,b.event,b. ...

  3. linearLayout 和 relativeLayout的属性区别

    LinearLayout和RelativeLayout 共有属性: java代码中通过btn1关联次控件 android:id="@+id/btn1" 控件宽度 android:l ...

  4. SkipList跳表(一)基本原理

    一直听说跳表这个数据结构,说要学一下的,懒癌犯了,是该治治了 为什么选择跳表 目前经常使用的平衡数据结构有:B树.红黑树,AVL树,Splay Tree(这个树好像还没有听说过),Treep(也没有听 ...

  5. linux SPI驱动——spi core(四)

    一: SPI核心,就是指/drivers/spi/目录下spi.c文件中提供给其他文件的函数,首先看下spi核心的初始化函数spi_init(void). 1: static int __init s ...

  6. eclipse tomcat maven

    jdk jre eclipse 略过 下载maven和tomcat 上apache官网下载maven:http://maven.apache.org/download.cgi. 上apache官网下载 ...

  7. H2 应用实例2

    DIY 博客全文界面的推荐.反对.加关注.返回顶部.快速评论等小功能的集成 --> 转载 :一.搭建测试环境和项目 1.1.搭建JavaWeb测试项目 创建一个[H2DBTest]JavaWeb ...

  8. 开源Flex Air版免费激情美女视频聊天室,免费网络远程视频会议系统((Flex,Fms3联合打造))

    开源Flex Air版免费激情美女视频聊天室,免费网络远程视频会议系统((Flex,Fms3联合打造))   Flex,Fms3系列文章导航 Flex,Fms3相关文章索引 本篇是视频聊天,会议开发实 ...

  9. SAP采购寄售业务操作步骤

    [转自 http://blog.sina.com.cn/s/blog_6466e5f70100jghg.html] 这里所示的是比较完整的步骤,包含了:信息记录.采购合同.货源清单.采购申请.采购订单 ...

  10. 如何修改硬盘挂载的名字LABEL

    ➜ ~ df -h Filesystem Size Used Avail Use% Mounted on/dev/sda2 114G 97G 12G 90% /media/brian/4ef34b75 ...