WPF:浅析Dispatcher
本人文笔差。还是直接上代码吧。(本文假设你对WPF中的Dispatcher有一定的了解)
你觉得下面的代码可以正常执行吗?
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread t = new Thread(() =>
{
while (true)
{
new Window().Show();
Thread.Sleep();
}
});
t.Start();
}
WPF的操作UI的线程必须是单线程单元模型(STA),也就是必须把线程的单元状态设置为STA才可以操作UI对象。
上面的代码,并没有设置线程的单元状态,线程的默认单元状态为:System.Threading.ApartmentState.Unknown
通过下面的代码可以设置线程的单元状态为STA:
t.TrySetApartmentState(ApartmentState.STA);
修改后的代码如下:(可以正常运行)
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread t = new Thread(() =>
{
while (true)
{
new Window().Show();
Thread.Sleep();
}
});
t.TrySetApartmentState(ApartmentState.STA);
t.Start();
}
接下来,对代码再做一点修改,你觉得下面的代码是否可以正常运行呢?
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread t = new Thread(() =>
{
while (true)
{
Window win = new Window(); this.Dispatcher.Invoke(new Action(delegate
{
win.Show();
}));
Thread.Sleep();
}
}); t.TrySetApartmentState(ApartmentState.STA);
t.Start();
}
在一个线程中创建的UI对象,也只能是创建该UI对象的线程才能访问它。如果其他线程要访问这个UI对象,需要通过创建UI线程的Dispatcher才能实现。
上面的代码,win对象实际上是t这个线程创建的。而执行win.Show()这个动作的却是另外这个线程(实际上是主UI线程),所以上面的代码也是不能正常执行的。
需要注意的是,只有当一个线程中执行过UI操作后,这个线程才具有Dispatcher,然后其他线程可以通过这个Dispatcher去访问该线程创建的UI对象。一个没有执行任何UI操作的线程,其Dispatcher为null.
通过Dispatcher的静态方法FromThread可以获取一个线程关联的Dispatcher对象。如果你觉得上面的这句话不好理解,可以看看下面的图:

看以看到,在没有执行UI操作之前,线程t的Dispatcher对象的值为null,当执行完Window win = new Window();后(也就是执行了一个UI操作),t线程关联的Dispatcher就有值了。
总结:
- 任何线程中如果想执行UI操作,那么其线程单元必须设置为STA。
- 一个线程如果创建了UI对象,那么这个UI对象就只能被这个线程管理。
- 任何线程如果需要访问其他的线程创建的UI对象,只能通过其他线程的Dispatcher进行访问
- 一个线程如果没有执行任何UI操作,那么其关联的Dispatcher为null
WPF:浅析Dispatcher的更多相关文章
- WPF 线程 Dispatcher
WPF 应用程序从两个线程开始: 一个用于处理呈现 一个用于管理 UI 呈现线程有效地隐藏在后台运行,而UI线程则接收输入.处理事件.绘制屏幕以及运行应用程序代码. 大多数应用程序都使用一个 UI 线 ...
- WPF中Dispatcher未捕获异常之处理
在UI线程中 在APP.XAML中定义 DispatcherUnhandledException事件 在工作线程中 PageMain.GetInstance().Dispatcher.Invoke(( ...
- 【WPF】Dispatcher及线程操作
WPF 应用程序启动后,会有两个线程: 1. 一个是用来处理UI呈现(处理UI的请求,比如输入和展现等操作). 2. 一个用来管理 UI的 (对UI元素及整个UI进行管理). 像Winform一样,W ...
- wpf 的dispatcher
wpf项目中后台代码调用界面控件时,会提示进程调用的错误. private Thread JxThread = null; //定义线程 private DataLoading.Loading nL ...
- WPF基础:Dispatcher介绍
Disaptcher作用 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个线程,其中有一个是主线程,其余的是子线程.在WPF或WinForm应用程序中,主线程负 ...
- 调用线程无法访问此对象,因为另一个线程拥有该对象 [c# wpf定时器程序报的错误]
WPF:Dispatcher.Invoke 方法,只有在其上创建 Dispatcher 的线程才可以直接访问DispatcherObject.若要从不同于在其上创建 DispatcherObject ...
- WPF [调用线程无法访问此对象,因为另一个线程拥有该对象。] 解决方案以及如何实现字体颜色的渐变
本文说明WPF [调用线程无法访问此对象,因为另一个线程拥有该对象.] 解决方案以及如何实现字体颜色的渐变 先来看看C#中Timer的简单说明,你想必猜到实现需要用到Timer的相关知识了吧. C# ...
- 2018-2-13-wpf-使用-Dispatcher.Invoke-冻结窗口
title author date CreateTime categories wpf 使用 Dispatcher.Invoke 冻结窗口 lindexi 2018-2-13 17:23:3 +080 ...
- .Net中的AOP系列之《间接调用——拦截方法》
返回<.Net中的AOP>系列学习总目录 本篇目录 方法拦截 PostSharp方法拦截 Castle DynamicProxy方法拦截 现实案例--数据事务 现实案例--线程 .Net线 ...
随机推荐
- Hibernate内容详解
一:引入Hibernate的jar包 http://t.cn/EioD1xk 二:配置Hibernate的核心配置文件hibernate.cfg.xml <!DOCTYPE hibernate- ...
- Golang 入门 : 结构体(struct)
Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型.试图表示一个现实世界中的实体. 结构体由一系列命名的元素组成,这些元素又被称为字段,每个字段都有一个名称和 ...
- 从零单排学Redis【铂金二】
前言 只有光头才能变强 好的,今天我们要上[铂金二]了,如果还没有上铂金的,赶紧先去蹭蹭经验再回来(不然不带你上分了): 从零单排学Redis[青铜] 从零单排学Redis[白银] 从零单排学Redi ...
- Asp.Net Core使用SignalR进行服务间调用
网上查询过很多关于ASP.NET core使用SignalR的简单例子,但是大部分都是简易聊天功能,今天心血来潮就搞了个使用SignalR进行服务间调用的简单DEMO. 至于SignalR是什么我就不 ...
- Docker最全教程之Go实战,墙裂推荐(十八)
前言 与其他语言相比,Go非常值得推荐和学习,真香!为什么?主要是可以直接编译成机器代码(性能优越,体积非常小,可达10来M,见实践教程图片)而且设计良好,上手门槛低.本篇主要侧重于讲解了Go语言的优 ...
- SQL server脚本语句积累
1:往现有的表中增加一个字段 IF NOT EXISTS ( SELECT 1 FROM sys.sysobjects so WITH ( NOLOCK ) INNER JOIN sys.syscol ...
- C语言超级搞笑的代码,冷笑话我们程序员也会讲的啊!
百年修得足下点击本文 欢迎来到"C语言基础"专题,今天我们放松一天,不学习知识,来看下大千世界的千奇百怪的C语言代码,你见过那些? 1.关于随机数这回事 这个随机数有点意思哦. 2 ...
- SQL过滤字符后手工注入漏洞测试(第1题)
https://www.mozhe.cn/bug/detail/a1diUUZsa3ByMkgrZnpjcWZOYVEyUT09bW96aGUmozhe 分析题目,属于时间盲注,这种情况,通常使用sq ...
- 我们是如何通过全球第一免费开源ERP Odoo做到项目100%交付
传统友商ERP的交付过程 一.先初步需求调研,后选型功能模块 传统友商ERP第一件事情先对客户方进行初步的调研,客户方无论说什么,友商听过算过,只关心你人数多少,有哪些人涉及到哪些模块,接着对模块进行 ...
- ArcGIS API for JavaScript 入门教程[5] 再讲数据——Map类之底图与高程
[回顾]前4篇交代了JsAPI的背景.资源如何获取,简介了数据与视图分离的概念与实现,剖析了页面的大骨架. 这篇开始,讲Map类. 转载注明出处,博客园/CSDN/B站/知乎:秋意正寒 目录:http ...