WPF Dispatcher使用】的更多相关文章

几个月之前因为项目需要,需要实现一个类似于WPF Dispatcher类的类,来实现一些线程的调度.之前因为一直做Asp.Net,根本没有钻到这个层次去,做的过程中,诸多不顺,重构了四五次,终于实现,满足项目要求. Dispatcher的源码对我来说,看的确实很累,各种累关联,不知所云.当时仅有的周永恒的博客看了六七遍也只是知道了大概的轮廓.今天我这里讲的,就是按照当时的项目需求的方向所理解和收获的一些知识,分享出来.太全面的东西,我讲出来只怕误人子弟了,大家还是去参照老周的博客吧.O(∩_∩)…
在上一篇文章 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分) 中我们发现 Dispatcher.Invoke 方法内部是靠 Dispatcher.PushFrame 来确保"不阻塞地等待"的.然而它是怎么做到"不阻塞地等待"的呢? 阅读本文将更深入地了解 Dispatcher 的工作机制. 本文是深入了解 WPF Dispatcher 的工作原理系列文章的一部分: Invoke/InvokeAsync 部分 Push…
深耕 WPF 开发的各位程序员大大们一定避不开使用 Dispatcher.跨线程访问 UI 当然免不了用到它,将某个任务延迟到当前任务之后执行也会用到它.Dispatcher.Invoke.Dispatcher.BeginInvoke 是过去大家经常使用的方法,而 .Net Framework 4.5 中微软为我们带来了 Dispatcher.InvokeAsync 方法,它和前面两个有何不同? 阅读本文将更深入地了解 Dispatcher 的工作机制. 本文是深入了解 WPF Dispatch…
问题 WPF Dispatcher 提供了UI线程之外的线程异步操作(请求)UI变化.一次Invoke/BeginInvoke调用产生一个DispatcherOperation,将挂在调度队列中,按照优先级被UI执行. 那么问题来了.频繁调用Invoke,比如100+Update/s,将产生极大的性能问题,包括线程上下文切换等. 解决思路 将多个Update封装到一个DispatcherOperation中:这种情况可有效提升性能,打算性能/效果相互抵制:(这个具体实现可参考网上的一篇文章:使用…
微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢?Dispatcher的作用是用于管理线程工作项队列.主线程负责接收输入.处理事件.绘制屏幕等工作,这样一来,UI界面是主线程创建的,因为子线程不能直接更新由主线程维护的UI界面,所有调用Dispatcher更新UI. 实例:WPF更新UI方式一 new Thread(()=>{ this.Dispatcher.Invoke(new Action(()=>{ //通知主线程去完成更新 })); }).Star…
 <Window x:Class="DispatcherExam.MainWindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         Title="MainWindow" H…
微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢?Dispatcher的作用是用于管理线程工作项队列.主线程负责接收输入.处理事件.绘制屏幕等工作,这样一来,UI界面是主线程创建的,因为子线程不能直接更新由主线程维护的UI界面,所有调用Dispatcher更新UI. 实例:WPF更新UI方式一new Thread(()=>{    this.Dispatcher.Invoke(new Action(()=>{        //通知主线程去完成更新    …
在开发WPF应用时出现:”调用线程无法访问此对象,因为另一个线程拥有该对象.“ 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者Invoke()方法. Dispatcher.BeginInvoke() //异步执行,不等待委托结束就更新 Dispatcher.Invoke()          //代表同步执行 Action()                            //委托 this.Dispatcher.B…
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/bl…
一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了.稍后我会上传我的代码,包含测试程序以及之前两边博文谈到的控件,这里我还实现了一个类似雷达扫描的等待窗体,大家可以稍后查看. 实际上这里只有两个难点需要处理,一个就是如何让子窗体遮挡主窗体并位于主窗体中间,另一个就是委托及跨线程访问UI界面.为了方便调用,我在这里写了一个静态的子线程窗体管理类Dial…
首先要检查那些滥用 Timer.Dispacher Timer 或者滥用什么“线程+死循环+阻塞”轮询的代码. 这种是编程大忌,有些人不会设计事件驱动程序,而是滥用轮询. 若是:触发事件后的假死,搜WPF  Dispatcher…
接上文: Windows 消息循环(1) - 概览 win32/MFC/WinForm/WPF 都依靠消息循环驱动,让程序跑起来. 本文介绍 WPF 中是如何使用消息循环来驱动程序的. 4 消息循环在 WPF 中的应用 4.1 引入 只听说过 Dispatcher ,哪里来的消息循环? 先瞧一眼 WPF 启动运行堆栈: 可以发现 PushFrameImpl 这个方法. 去看其源码,就发现了熟悉的消息循环 : 可以理解为:Dispatcher 对消息循环的操作进行了"封装" . 那,Di…
原文:WPF 渲染原理 在 WPF 最主要的就是渲染,因为 WPF 是一个界面框架.想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的.本文告诉大家 WPF 从开发者告诉如何画图像到在屏幕显示的过程.本文是从一个很高的地方来看渲染的过程,在本文之后会添加很多博客来告诉大家渲染的细节. 目录 WPF 组成 托管层 非托管层 核心系统层 消息循环 Dispatcher 调度 RenderContent 桌面窗口管理 从控件画出来到屏幕显示 从 WPF 画图像到屏幕显示是比较复杂的,本渣也不敢…
title author date CreateTime categories wpf 使用 Dispatcher.Invoke 冻结窗口 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23:3 +0800 WPF 性能优化 如果使用Dispatcher.Invoke实际上会有一个坑,在执行Dispatcher.Invoke刚好拖动窗口就会出现窗口冻结,这时使用 Alt+Tab 可以解决. 这个问题是在我写wpf DoEvents发现的,因为Dispa…
Yield 这个词很有意思,叫做“屈服”“放弃”“让步”,字面意义上是让出当前任务的执行权,转而让其他任务可以插入执行.Task.Dispatcher.Thread 都有 Yield() 方法,看起来都可以让出当前任务的执行权. 如果在阅读中发现对本文涉及到的一些概念不太明白,可以阅读: 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分) 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分) Dispatcher.Yield…
WPF只允许UI线程修改UI,其他线程必须通过Invoke.委托(安全性)Winform可以开启/关闭“只允许UI线程修改UI” 在WPF中非UI线程修改UI的方法 非UI线程直接修改UI,会报错 System.InvalidOperationException:“调用线程无法访问此对象,因为另一个线程拥有该对象.” 正确的做法是 Task t = new Task(() => { NameLabel.Dispatcher.Invoke(new Action(delegate { NameLab…
当我们遇到一些异步执行又无法等待时的逻辑,比如动画的执行. 而业务上又需要等待逻辑的完成,再去处理后续的操作.这时需要转成异步方法 如下,同步执行一个动画后,再输出日志: private async void TaskCompleteSourceAwait_OnClick(object sender, RoutedEventArgs e) { )) }); Debug.WriteLine($"TaskCompleteSourceAwait_OnClick end:{isCompleted}&qu…
异步转同步-PushFrame 本文通过PushFrame,实现异步转同步 首先有一个异步方法,如下异步任务延时2秒后,返回一个结果 private static async Task<string> TestWithResultAsync() { Debug.WriteLine("1. 异步任务start……"); ); Debug.WriteLine("2. 异步任务end……"); return "2秒以后"; } 在UI线程执…
title author date CreateTime categories WPF 渲染原理 lindexi 2019-9-8 10:40:0 +0800 2018-7-15 16:2:47 +0800 WPF 渲染 在 WPF 最主要的就是渲染,因为 WPF 是一个界面框架.想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的.本文告诉大家 WPF 从开发者告诉如何画图像到在屏幕显示的过程.本文是从一个很高的地方来看渲染的过程,在本文之后会添加很多博客来告诉大家渲染的细节. 从 WP…
title author date CreateTime categories win10 uwp 禁止编译器优化代码 lindexi 2018-08-10 19:16:50 +0800 2018-2-13 17:23:3 +0800 Win10 UWP 有时候写了一些代码,但是在优化代码的时候出错,但是如果不优化代码,性能很差.如何让编译器不优化一段代码? 一般发布的软件都会选优化代码,点击属性选择生成就可以看到优化代码 假如有方法 Foo ,这个方法里面写了一些特殊代码,不想让编译器优化,那…
C# 中 ConfigureAwait 相关答疑FAQ 在前段时间经常看到园子里有一些文章讨论到 ConfigureAwait,刚好今天在微软官方博客看到了 Stephen Toub 前不久的一篇答疑 ConfigureAwait 的一篇文章,想翻译过来. 原文地址:https://devblogs.microsoft.com/dotnet/configureawait-faq/ .NET 加入 async/await 特性已经有 7 年了.这段时间,它蔓延的非常快,广泛:不只在 .NET 生态…
原文: https://devblogs.microsoft.com/dotnet/configureawait-faq/ .NET 在七多年前在语言和类库添加了 async/await .在那个时候,它像野火一样流行,不仅遍及.NET生态系统,而且还可以以多种其他语言和框架进行复制.在利用异步的其他语言构造,提供异步支持的API以及进行async/ await相关的基础架构方面的基本改进方面,.NET也实现了很多改进(特别是.NET Core的性能和支持诊断的改进) . 但是,async/ a…
WPF 应用程序从两个线程开始: 一个用于处理呈现 一个用于管理 UI 呈现线程有效地隐藏在后台运行,而UI线程则接收输入.处理事件.绘制屏幕以及运行应用程序代码. 大多数应用程序都使用一个 UI 线程,但在某些情况下,最好使用多个线程.我们将在后面举例说明这一点. UI 线程对一个名为 Dispatcher 的对象内的工作项进行排队. Dispatcher基于优先级选择工作项,并运行每一个工作项,直到完成.每个UI线程都必须至少有一个Dispatcher,并且每个 Dispatcher 都只能…
一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个线程,其中有一个是主线程,其余的是子线程.在WPF或WinForm应用程序中,主线程负责接收输入.处理事件.绘制屏幕等工作,为了使主线程及时响应,防止假死,在开发过程中对一些耗时的操作.消耗资源比较多的操作,都会去创建一个或多个子线程去完成操作,比如大数据量的循环操作.后台下载.这样一来,由…
在UI线程中 在APP.XAML中定义 DispatcherUnhandledException事件 在工作线程中 PageMain.GetInstance().Dispatcher.Invoke((MethodInvoker)delegate  { throw ex;} 任何当前Dispatcher线程(即UI线程)的未处理异常都可以选择处理或者不处理(通过DispatcherUnhandledExceptionEventArgs.IsHandled属性),选择处理的话未处理异常就不会崩溃整个…
使用WPF开发时经常会遇上自己建立的线程需要更新界面UI内容,从而导致的跨线程问题. 异常内容: 异常类型:System.InvalidOperationException 异常描述: "System.InvalidOperationException"类型的未经处理的异常在 WindowsBase.dll 中发生 其他信息: 调用线程无法访问此对象,因为另一个线程拥有该对象. 在WPF中最简便的解决此问题的方法就是使用Dispatcher. 1.最便捷的使用Dispatcher th…
WPF 应用程序启动后,会有两个线程: 1. 一个是用来处理UI呈现(处理UI的请求,比如输入和展现等操作). 2. 一个用来管理 UI的 (对UI元素及整个UI进行管理). 像Winform一样,WPF在线程里面是不可以直接操作UI元素,如果在一个非UI线程里操作UI元素,将会报错! XAML代码如下: <Window x:Class="WpfApp1112.Window1" xmlns="http://schemas.microsoft.com/winfx/2006…
本人文笔差.还是直接上代码吧.(本文假设你对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…
DispatcherObject,Dispatcher,Thread之间的关系 我们都知道WPF中的控件类都是从System.Windows.Threading.DispatcherObject继承而来, 而DispatcherObject又在构造时与当前线程的Dispatcher关联起来,CurrentDispatcher如果为null则会主动new一个Dispatcher并且在构造时和当前创建它的线程关联起来了.因此整个链为DispatcherObject <- Dispatcher <-…
大家都知道在WPF中对非UI线程中要处理对UI有关的对象进行操作,一般需要使用委托的方式,代码基本就是下面的写法 App.Current.MainWindow.Dispatcher.Invoke(new Action(() => { //TODO:更改UI相关的操作 })); 我以前也总是如此写法,没出现过毛病,可是偏偏就在今日,我在串口接收事件中这样写报错了,错误提示说:“ 其他线程拥有此对象,此线程不能使用”,对于没有多少底子的我当时肯定是一脸蒙圈了,还是去群里问问吧,一问果 然是高手给出了…