• DispatcherObject & DependencyObject


    以下内容摘自MSDN 

    DispatcherObject & DependencyObject

    System.Threading.DispatcherObject

    --------------------------------------------------------------------------------

    Most objects in WPF derive from DispatcherObject, which provides the basic constructs for dealing with concurrency and threading.WPF is based on a messaging system implemented by the dispatcher.This works much like the familiar Win32 message pump; in fact, the WPF dispatcher uses User32 messages for performing cross thread calls.

    There are really two core concepts to understand when discussing concurrency in WPF – the dispatcher and thread affinity. During the design phase of WPF, the goal was to move to a single thread of execution, but a non-thread "affinitized" model.Thread affinity happens when a component uses the identity of the executing thread to store some type of state.The most common form of this is to use the thread local store (TLS) to store state.Thread affinity requires that each logical thread of execution be owned by only one physical thread in the operating system, which can become memory intensive.In the end, WPF’s threading model was kept in sync with the existing User32 threading model of single threaded execution with thread affinity.The primary reason for this was interoperability – systems like OLE 2.0, the clipboard, and Internet Explorer all require single thread affinity (STA) execution.

    Given that you have objects with STA threading, you need a way to communicate between threads, and validate that you are on the correct thread.Herein lies the role of the dispatcher.The dispatcher is a basic message dispatching system, with multiple prioritized queues.Examples of messages include raw input notifications (mouse moved), framework functions (layout), or user commands (execute this method).By deriving from DispatcherObject, you create a CLR object that has STA behavior, and will be given a pointer to a dispatcher at creation time.

    WPF 中的大多数对象是从 DispatcherObject 派生的,这提供了用于处理并发和线程的基本构造。WPF 基于调度程序实现的消息系统。其工作方式与常见的 Win32 消息泵非常类似;事实上,WPF 调度程序使用 User32 消息执行跨线

    程调用。

    要讨论 WPF 中的并发,首先必须真正理解两个核心概念 – 调度程序和线程关联。

    在 WPF 的设计阶段,目标趋向于单一线程的执行,但这不是一种与线程“关联的”模型。当一个组件使用执行线程的标识来存储某种类型的状态时,将发生线程关联。最常见的形式是使用线程本地存储 (TLS) 来存储状态。线程关联

    要求执行的每个逻辑线程仅由操作系统中的一个物理线程所拥有,这将占用大量内存。最后,WPF 的线程处理模型保持与具有线程关联的单一线程执行的现有 User32 线程处理模型同步。主要原因是互操作性 – 类似于 OLE 2.0 的

    系统、剪贴板和 Internet Explorer 均需要单一线程关联 (STA) 执行。

    假设您具有带有 STA 线程的对象,则需要一种方式来在线程之间通信,并验证您是否位于正确的线程上。调度程序的作用就在于此。调度程序是一个基本的消息调度系统,具有多个按优先级排列的队列。消息的示例包括原始输入通

    知(鼠标移动)、框架函数(布局)或用户命令(执行此方法)。通过从 DispatcherObject 派生,您可以创建一个具有 STA 行为的 CLR 对象,并在创建时获得一个指向调度程序的指针。

    Only the thread that the Dispatcher was created on may access the DispatcherObject directly.To access a DispatcherObject from a thread other than the thread the DispatcherObject was created on, call  Invoke or BeginInvoke on the Dispatcher the DispatcherObject is associated with.

    只有在其上创建 Dispatcher 的线程才可以直接访问 DispatcherObject。若要从不同于在其上创建 DispatcherObject 的线程的某个线程访问 DispatcherObject,请对与 DispatcherObject 关联的 Dispatcher 调用 Invoke 或 BeginInvoke。

    Invoke is synchronous and BeginInvoke is asynchronous

      // 摘要:

        //     表示与 System.Windows.Threading.Dispatcher 关联的对象。

        public abstract class DispatcherObject

        {

            // 摘要:

            //     初始化 System.Windows.Threading.DispatcherObject 类的一个新实例。

            protected DispatcherObject();

            // 摘要:

            //     获取与此 System.Windows.Threading.DispatcherObject 关联的 System.Windows.Threading.Dispatcher。

            //

            // 返回结果:

            //     调度程序。

            [EditorBrowsable(EditorBrowsableState.Advanced)]

            public Dispatcher Dispatcher { get; }

            // 摘要:

            //     确定调用线程是否可以访问此 System.Windows.Threading.DispatcherObject。

            //

            // 返回结果:

            //     如果调用线程可以访问此对象,则为 true;否则,为 false。

            [EditorBrowsable(EditorBrowsableState.Never)]

            public bool CheckAccess();

            //

            // 摘要:

            //     强制调用线程具有此 System.Windows.Threading.DispatcherObject 的访问权限。

            //

            // 异常:

            //   System.InvalidOperationException:

            //     调用线程不可以访问此 System.Windows.Threading.DispatcherObject。

            [EditorBrowsable(EditorBrowsableState.Never)]

            public void VerifyAccess();

        }

    System.Windows.DependencyObject

    --------------------------------------------------------------------------------

    One of the primary architectural philosophies used in building WPF was a preference for properties over methods or events.Properties are declarative and allow you to more easily specify intent instead of action.This also supported a model driven, or data driven, system for displaying user interface content.This philosophy had the intended effect of creating more properties that you could bind to, in order to better control the behavior of an application.

    In order to have more of the system driven by properties, a richer property system than what the CLR provides was needed.A simple example of this richness is change notifications.In order to enable two way binding, you need both sides of the bind to support change notification.In order to have behavior tied to property values, you need to be notified when the property value changes.The Microsoft .NET Framework has an interface, INotifyPropertyChange, which allows an object to publish change notifications, however it is optional.

    WPF provides a richer property system, derived from the DependencyObject type.The property system is truly a "dependency" property system in that it tracks dependencies between property expressions and automatically revalidates property values when dependencies change.For example, if you have a property that inherits (like FontSize), the system is automatically updated if the property changes on a parent of an element that inherits the value.

    The foundation of the WPF property system is the concept of a property expression.In this first release of WPF, the property expression system is closed, and the expressions are all provided as part of the framework.Expressions are why the property system doesn’t have data binding, styling, or inheritance hard coded, but rather provided by later layers within the framework.

    The property system also provides for sparse storage of property values.Because objects can have dozens (if not hundreds) of properties, and most of the values are in their default state (inherited, set by styles, etc.), not every instance of an object needs to have the full weight of every property defined on it.

    The final new feature of the property system is the notion of attached properties.WPF elements are built on the principle of composition and component reuse.It is often the case that some containing element (like a Grid layout element) needs additional data on child elements to control its behavior (like the Row/Column information).Instead of associating all of these properties with every element, any object is allowed to provide property definitions for any other object.This is similar to the "expando" features of JavaScript.

    生成 WPF 时使用的主要体系结构原理之一是首选属性而不是方法或事件。属性是声明性的,使您更方便地指定意图而不是操作。它还支持模型驱动或数据驱动的系统,以显示用户界面内容。这种理念的预期效果是创建您可以绑定到的更多属性,从而更好地控制应用程序的行为。

    为了更加充分地利用由属性驱动的系统,需要一个比 CLR 提供的内容更丰富的属性系统。此丰富性的一个简单示例就是更改通知。为了实现双向绑定,您需要绑定的双方支持更改通知。为了使行为与属性值相关联,您需要在属性值更改时得到通知。Microsoft .NET Framework 具有一个 INotifyPropertyChange 接口,对象通过该接口可以发布更改通知,但该接口是可选的。

    WPF 提供一个丰富的属性系统,该属性系统是从 DependencyObject 类型派生的。该属性系统实际是一个“依赖”属性系统,因为它会跟踪属性表达式之间的依赖关系,并在依赖关系更改时自动重新验证属性值。例如,如果您具有一个会继承的属性(如 FontSize),当继承该值的元素的父级发生属性更改时,会自动更新系统。

    WPF 属性系统的基础是属性表达式的概念。在 WPF 的第一版中,属性表达式系统是关闭的,表达式都是作为框架的一部分提供的。表达式致使属性系统不具有硬编码的数据绑定、样式调整或继承,而是由框架内后面的层来提供这些功能。

    属性系统还提供属性值的稀疏存储。因为对象可以有数十个(如果达不到上百个)属性,并且大部分值处于其默认状态(被继承、由样式设置等),所以并非对象的每个实例都需要具有在该对象上定义的每个属性的完全权重。

    属性系统的最后一个新功能是附加属性的概念。WPF 元素是基于组合和组件重用的原则生成的。某些包含元素(如 Grid 布局元素)通常需要子元素上的其他数据才能控制其行为(如行/列信息)。任何对象都可以为任何其他对象提

    供属性定义,而不是要将所有这些属性与每个元素相关联。这与 JavaScript 中的“expando”功能相似。

    The property system's primary function is to compute the values of properties, and to provide system notification about values that have changed.Another key class that participates in the property system is DependencyProperty. DependencyProperty enables the registration of dependency properties into the property system, and provides identification and information about each dependency property, whereas DependencyObject as a base class enables objects to use the dependency properties.

    属性系统的主要功能是计算属性的值,并提供有关值已更改的系统通知。参与属性系统的另一个关键类是 DependencyProperty。DependencyProperty 可实现在属性系统中注册依赖项属性,并提供有关每个依赖项属性的标识和信息,而 DependencyObject 作为一个基类则使对象能够使用依赖项属性。

        // 摘要:

        //     表示一个参与依赖项属性系统的对象。

        [TypeDescriptionProvider(typeof(DependencyObjectProvider))]

        public class DependencyObject : DispatcherObject

        {

            // 摘要:

            //     初始化 System.Windows.DependencyObject 类的一个新实例。

            public DependencyObject();

            // 摘要:

            //     获取对此实例的 CLR 类型进行包装的 System.Windows.DependencyObjectType。

            //

            // 返回结果:

            //     对此实例的 CLR 类型进行包装的 System.Windows.DependencyObjectType。

            public DependencyObjectType DependencyObjectType { get; }

            //

            // 摘要:

            //     获取一个值,该值声明此实例当前是否为只读。

            //

            // 返回结果:

            //     如果此实例是密封的,则为 true;否则为 false。

            public bool IsSealed { get; }

            // 摘要:

            //     清除属性的本地值。要清除的属性由 System.Windows.DependencyProperty 标识符指定。

            //

            // 参数:

            //   dp:

            //     要清除的依赖项属性,由 System.Windows.DependencyProperty 对象引用标识。

            //

            // 异常:

            //   System.InvalidOperationException:

            //     试图对密封的 System.Windows.DependencyObject 调用 System.Windows.DependencyObject.ClearValue(System.Windows.DependencyProperty)。

            public void ClearValue(DependencyProperty dp);

            //

            // 摘要:

            //     清除只读属性的本地值。要清除的属性由 System.Windows.DependencyPropertyKey 指定。

            //

            // 参数:

            //   key:

            //     要清除的依赖项属性的键。

            //

            // 异常:

            //   System.InvalidOperationException:

            //     试图对密封的 System.Windows.DependencyObject 调用 System.Windows.DependencyObject.ClearValue(System.Windows.DependencyProperty)。

            public void ClearValue(DependencyPropertyKey key);

            //

            // 摘要:

            //     强制转换所指定依赖项属性的值。当依赖项属性存在于调用 System.Windows.DependencyObject 上时,可通过调用依赖项属性的属性元数据中指定的任何

            //     System.Windows.CoerceValueCallback 函数来实现此目的。

            //

            // 参数:

            //   dp:

            //     要强制转换的依赖项属性的标识符。

            //

            // 异常:

            //   System.InvalidOperationException:

            //     指定的 dp 或它的值无效或不存在。

            public void CoerceValue(DependencyProperty dp);

            //

            // 摘要:

            //     确定提供的 System.Windows.DependencyObject 是否等效于当前 System.Windows.DependencyObject。

            //

            // 参数:

            //   obj:

            //     要与当前实例进行比较的 System.Windows.DependencyObject。

            //

            // 返回结果:

            //     如果两个实例相同,则为 true;否则为 false。

            public override sealed bool Equals(object obj);

            //

            // 摘要:

            //     获取此 System.Windows.DependencyObject 的哈希代码。

            //

            // 返回结果:

            //     有符号的 32 位整数哈希代码。

            public override sealed int GetHashCode();

            //

            // 摘要:

            //     创建一个专用的枚举数,用于确定哪些依赖项属性在此 System.Windows.DependencyObject 上具有以本地方式设置的值。

            //

            // 返回结果:

            //     一个专用的本地值枚举数。

            public LocalValueEnumerator GetLocalValueEnumerator();

            //

            // 摘要:

            //     返回 System.Windows.DependencyObject 的此实例上的依赖项属性的当前有效值。

            //

            // 参数:

            //   dp:

            //     要为其检索值的属性的 System.Windows.DependencyProperty 标识符。

            //

            // 返回结果:

            //     返回当前的有效值。

            //

            // 异常:

            //   System.InvalidOperationException:

            //     指定的 dp 或其值无效,或者指定的 dp 不存在。

            public object GetValue(DependencyProperty dp);

            //

            // 摘要:

            //     重新计算指定依赖项属性的有效值

            //

            // 参数:

            //   dp:

            //     要使其失效的属性的 System.Windows.DependencyProperty 标识符。

            public void InvalidateProperty(DependencyProperty dp);

            //

            // 摘要:

            //     每当更新此 System.Windows.DependencyObject 上的任何依赖项属性的有效值时调用。更改的特定依赖项属性将在事件数据中报告。

            //

            // 参数:

            //   e:

            //     将包含相关依赖项属性标识符、类型的属性元数据以及旧值和新值的事件数据。

            protected virtual void OnPropertyChanged(DependencyPropertyChangedEventArgs e);

            //

            // 摘要:

            //     返回依赖项属性的本地值(如果存在)。

            //

            // 参数:

            //   dp:

            //     要为其检索值的属性的 System.Windows.DependencyProperty 标识符。

            //

            // 返回结果:

            //     返回本地值,或在未设置本地值的情况下返回 sentinel 值 System.Windows.DependencyProperty.UnsetValue。

            public object ReadLocalValue(DependencyProperty dp);

            //

            // 摘要:

            //     设置依赖项属性的本地值,该依赖项属性由其标识符指定。

            //

            // 参数:

            //   dp:

            //     要设置的依赖项属性的标识符。

            //

            //   value:

            //     新的本地值。

            //

            // 异常:

            //   System.InvalidOperationException:

            //     试图修改只读依赖项属性,或试图修改密封 System.Windows.DependencyObject 上的属性。

            //

            //   System.ArgumentException:

            //     value 的类型不是为 dp 属性注册时使用的正确类型。

            public void SetValue(DependencyProperty dp, object value);

            //

            // 摘要:

            //     设置只读依赖项属性的本地值,该依赖项属性由其 System.Windows.DependencyPropertyKey 标识符指定。

            //

            // 参数:

            //   key:

            //     要设置的属性的 System.Windows.DependencyPropertyKey 标识符。

            //

            //   value:

            //     新的本地值。

            public void SetValue(DependencyPropertyKey key, object value);

            //

            // 摘要:

            //     返回一个值,该值指示序列化进程是否应序列化提供的依赖项属性的值。

            //

            // 参数:

            //   dp:

            //     应序列化的依赖项属性的标识符。

            //

            // 返回结果:

            //     如果应对提供的依赖项属性的值进行序列化,则为 true;否则为 false。

            protected internal virtual bool ShouldSerializeProperty(DependencyProperty dp);

    继承层次结构

    --------------------------------------------------------------------------------

     System.Object

      System.Windows.Threading.DispatcherObject

        System.Windows.DependencyObject

          System.Windows.ContentElement

          System.Windows.Controls.DataGridColumn

          System.Windows.Controls.GridViewColumn

          System.Windows.Controls.TextSearch

          System.Windows.Controls.ViewBase

          System.Windows.Data.BindingGroup

          System.Windows.Data.CollectionContainer

          System.Windows.Data.CollectionViewSource

          System.Windows.Freezable

          System.Windows.Ink.GestureRecognizer

          System.Windows.Media.Media3D.Visual3D

          System.Windows.Media.Visual

          System.Windows.Navigation.JournalEntry

          System.Windows.TriggerAction

          System.Windows.TriggerBase

          System.Windows.VisualState

          System.Windows.VisualStateGroup

          System.Windows.VisualStateManager

          System.Windows.VisualTransition

  • 相关阅读:
    ZOJ 3656Bit Magic解题报告——2sat问题建图总结
    gcc和g++的区别
    07车展,流水账。。
    放开思维啊~~~
    SC2和其他
    幻觉~
    去横店咯~
    ETS。。New G。。
    老子毕业鸟。。。
    gcc常用参数和环境变量小结
  • 原文地址:https://www.cnblogs.com/xiaokang088/p/2037527.html
Copyright © 2020-2023  润新知