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. servletResponse 文件下载

    package response; import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOEx ...

  2. 【问】Windows下C++局部变量在内存中的分布问题

    原本是为了看看C++对象模型中子对象赋值给一个父对象和父类型指针指向的域时,到底会不会切割,就打开codebloks写了下面的代码,编译器选的是GNU. #define DEBUG(X) std::c ...

  3. Hadoop关于Wrong FS错误

    关于使用java api上传文件. 在定义一个FileSystem变量的时候伪分布式和单机版的方法是不一样的,单机版使用的是FileSystem类的静态函数 FileSystem hdfs = Fil ...

  4. 查看并修改Linux主机名命令hostname

    查看主机名 hostname可以查看主机名 export也可以查看 修改主机名 echo new-hostname > /proc/sys/kernel/hostname (系统启动时,从此文件 ...

  5. Flyweight Design Pattern 共享元设计模式

    就是利用一个类来完毕多种任务.不用每次都创建一个新类. 个人认为这个设计模式在C++里面,好像能够就使用一个函数取代,利用重复调用这个函数完毕任务和重复利用这个类,好像几乎相同. 只是既然是一个设计模 ...

  6. 限制UITextView的字数和字数监控,表情异常的情况和禁用表情

    限制UITextView的字数和字数监控,表情异常的情况和禁用表情   3523FD80CC4350DE0AE7F89A8532B9A8.png 因为字数占一个字符,表情占两个字符.你要是限制15个字 ...

  7. 可能是目前市面上唯一能够支持全平台的RTMP推流组件:Windows、Linux、Android、iOS、ARM

    EasyRTMP是什么? EasyRTMP是一套RTMP直播推送功能组件,内部集成了包括:基本RTMP协议.断线重连.异步推送.环形缓冲区.推送网络拥塞自动丢帧.缓冲区关键帧检索.事件回调(断线.音视 ...

  8. 用Darwin和live555实现的直播框架

    我们在开发视频直播或者监控类项目的时候,如场馆监控.学校监控.车载监控等等,往往首先希望的是形成一个项目的雏形,然后再在这个框架的基础上进行不断的完善和扩展工作,那么我们今天要给大家介绍的就是,如何形 ...

  9. CNN延拓至 复数域

  10. SecureCRT 会话设置项

    登陆动作------自动登陆仿真------两个颜色复选框都勾上模式------光标键模式(2个复选框)映射键------使用windows复制和粘贴热键外观------字符编码:UTF-8外观--- ...