一、Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个线程,其中有一个是主线程 ...
一、Dispatcher介绍
微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢?
不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个get='_blank'>线程,其中有一个是主线程,其余的是子线程。在WPF或WinForm应用程序中,主线程负责接收输入、处理事件、绘制屏幕等工作,为了使主线程及时响应,防止假死,在开发过程中对一些耗时的操作、消耗资源比较多的操作,都会去创建一个或多个子线程去完成操作,比如大数据量的循环操作、后台下载。这样一来,由于UI界面是主线程创建的,所以子线程不能直接更新由主线程维护的UI界面。
Dispatcher的作用是用于管理线程工作项队列,类似于Win32中的消息队列,Dispatcher的内部函数,仍然调用了传统的创建窗口类,创建窗口,建立消息泵等操作。Dispatcher本身是一个单例模式,构造函数私有,暴露了一个静态的CurrentDispatcher方法用于获得当前线程的Dispatcher。对于线程来说,它对Dispatcher是一无所知的,Dispatcher内部维护了一个静态的 List<Dispatcher> _dispatchers, 每当使用CurrentDispatcher方法时,它会在这个_dispatchers中遍历,如果没有找到,则创建一个新的Dispatcher对 象,加入到_dispatchers中去。Dispatcher内部维护了一个Thread的属性,创建Dispatcher时会把当前线程赋值给这个 Thread的属性,下次遍历查找的时候就使用这个字段来匹配是否在_dispatchers中已经保存了当前线程的Dispatcher。
二、Dispatcher的继承关系
在 WPF 的类层次结构中,大部分都集中派生于 DispatcherObject 类(通过其他类)。如下图 所示,您可以看到 DispatcherObject 虚拟类正好位于 Object 下方和大多数 WPF 类的层次结构之间。 要了解他们之间的关系可以参看下面这张类继承关系图:
对上图的一些说明:
1) System.Object 类:大家都知道在.Net中所有类型的基类,DispatcherObject 就继承于它,所以它是WPF的基类。
2) System.Windows.Threading.DispatcherObject 类:从图中看WPF 中的使用到的大部分控件与其他类大多是继承 DispatcherObject 类,它提供了用于处理并发和线程的基本构造。
3) System.Windows.DependencyObject类:对WPF中的依赖项属性承载支持与 附加属性承载支持,表示参与 依赖项属性 系统的对象。
4) System.Windows.Media.Visual类:为 WPF 中的呈现提供支持,其中包括命中测试、坐标转换和边界框计算等。
5) System.Windows.UIElement 类:UIElement 是 WPF 核心级实现的基类,该类是 Windows Presentation Foundation (WPF) 中具有可视外观并可以处理基本输入的大多数对象的基类。
6) System.Windows.FrameworkElement类:为 Windows Presentation Foundation (WPF) 元素提供 WPF 框架级属性集、事件集和方法集。此类表示附带的 WPF 框架级实现,它是基于由UIElement定义的 WPF 核心级 API 构建的。
7) System.Windows.Controls.Control 类:表示 用户界面 (UI) 元素的基类,这些元素使用 ControlTemplate 来定义其外观。
8) System.Windows.Controls.ContentControl类:表示没有任何类型的内容表示单个控件。
WPF的绝大部分的控件,还包括窗口本身都是继承自ContentControl的。
ContentControl族包含的控件
Button | ButtonBase | CheckBox | ComboBoxItem |
ContentControl | Frame | GridViewColumnHeader | GroupItem |
Label | ListBoxItem | ListViewItem | NavigationWindow |
RadioButton | RepeatButton | ScrollViewer | StatusBarItem |
ToggleButton | ToolTip | UserControl | Window |
9) System.Windows.Controls.ItemsControl 类:表示可用于提供项目的集合的控件。
以条目集合位内容的控件 ItemsControl
特点: a.均派生自ItemsControl
b.内容属性为Items或ItemsSource
c.每种ItemsControl都对应有自己的条目容器(Item Container).
ItemsControl族包含的控件
Menu | MenuBase | ContextMenu | ComboBox |
ItemsControl | ListBox | ListView | TabControl |
TreeView | Selector | StatusBar | |
10) System.Windows.Controls.Panel类:为所有 Panel 元素提供基类。 使用 Panel 元素定位和排列在 Windows Presentation Foundation (WPF) 应用程序的子对象。
11)System.Windows.Sharps.Sharp类:为 Ellipse、Polygon 和 Rectangle 之类的形状元素提供基类。
三、走进Dispatcher
所有 WPF 应用程序启动时都会加载两个重要的线程:一个用于呈现用户界面,另一个用于管理用户界面。呈现线程是一个在后台运行的隐藏线程,因此您通常面对的唯一线程 就是 UI 线程。WPF 要求将其大多数对象与 UI 线程进行关联。这称之为线程关联,意味着要使用一个 WPF 对象,只能在创建它的线程上使用。在其他线程上使用它会导致引发运行时异常。 UI 线程的作用是用于接收输入、处理事件、绘制屏幕以及运行应用程序代码。
在 WPF 中绝大部分控件都继承自 DispatcherObject,甚至包括 Application。这些继承自 DispatcherObject 的对象具有线程关联特征,也就意味着只有创建这些对象实例,且包含了 Dispatcher 的线程(通常指默认 UI 线程)才能直接对其进行更新操作。
DispatcherObject 类有两个主要职责:提供对对象所关联的当前 Dispatcher 的访问权限,以及提供方法以检查 (CheckAccess) 和验证 (VerifyAccess) 某个线程是否有权访问对象(派生于 DispatcherObject)。CheckAccess 与 VerifyAccess 的区别在于 CheckAccess 返回一个布尔值,表示当前线程是否可以使用对象,而 VerifyAccess 则在线程无权访问对象的情况下引发异常。通过提供这些基本的功能,所有 WPF 对象都支持对是否可在特定线程(特别是 UI 线程)上使用它们加以确定。如下图。
在 WPF 中,DispatcherObject 只能通过与它关联的 Dispatcher 进行访问。 例如,后台线程不能更新由 UI 线程创建的 Label的内容。
那么如何更新UI线程创建的对象信息呢?Dispatcher提供了两个方法,Invoke和BeginInvoke,这两个方法还有多个不同参数的重载。其中Invoke内部还是调用了BeginInvoke,一个典型的BeginInvoke参数如下:
public DispatcherOperation BeginInvoke(Delegate method, DispatcherPriority priority, params object[] args);
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:WPF入门教程系列四——Dispatcher介绍
关键词:wpf
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。