用 UI 多线程处理 WPF 大量渲染的解决方案
众所周知, WPF 的 UI 渲染是单线程的,所以如果我们异步或者新建线程去进行数据处理的时候,处理完,想要更新 UI 的时候,需要调用一下 Dispatcher.Invoke,将处理完的数据推入到 Dispatcher 中,等待更新界面,不然就会报调用线程无法访问此对象,因为另一个线程拥有该对象的错误。这也就是为什么所有 WPF 组件的父类都是 DependencyObject 的原因。
但是工作中,有时候会遇到 UI 密集型的情况,也就是界面不停渲染导致界面出现卡住的情况,这时候就是 Dispatcher 忙不过来了,一般这时候,都会想要用多线程来渲染界面,但是一个 Dispatcher 只能为一个线程服务,所以我一般会将这种 UI 密集型的界面,单独放到一个弹窗中,再新建一个 UI 线程并指定 Dispatcher 来渲染。
样例代码
代码也很简单,我直接贴啦!
我在界面中放了两个按钮,一个用来打开负责大量渲染的窗口,一个用来关闭该窗口。
Window w = null;
newWindowButton.Click += (sender, args) =>
{
var thread = new Thread(() =>
{
w = new Window
{
Content = new LargeRenderView(),
Width = 1200,
Height = 1000
};
w.Show();
Dispatcher.Run(); // 运行 Dispatcher,为新建的 UI 线程服务
});
thread.SetApartmentState(ApartmentState.STA); // // 指定线程为单线程模式
thread.Start();
};
closeWindowButton.Click += (sender, args) =>
{
w.Close();
if (w == null) return;
if (w.Dispatcher.CheckAccess())
w.Close();
else
w.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(w.Close));
};
效果
可以看到新弹窗因为大量渲染,鼠标一直在转圈,无法操作,但是主窗口还是可以进行 UI 操作,所以主窗口没有被这个大量渲染影响到。
最后
这业务场景还有什么有用的解决方案,请留言教教我!
觉得对你有帮助点个推荐或者留言交流一下呗!
源码 https://github.com/yijidao/blog/tree/master/WPF/Multithread
WPF 线程模型文档 https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/threading-model?redirectedfrom=MSDN&view=netframeworkdesktop-4.8
用 UI 多线程处理 WPF 大量渲染的解决方案的更多相关文章
- 美团开源Graver框架:用“雕刻”诠释iOS端UI界面的高效渲染
Graver 是一款高效的 UI 渲染框架,它以更低的资源消耗来构建十分流畅的 UI 界面.Graver 独创性的采用了基于绘制的视觉元素分解方式来构建界面,得益于此,该框架能让 UI 渲染过程变得更 ...
- C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- 通过分析 WPF 的渲染脏区优化渲染性能
原文:通过分析 WPF 的渲染脏区优化渲染性能 本文介绍通过发现渲染脏区来提高渲染性能. 本文内容 脏区 Dirty Region WPF 性能套件 脏区监视 优化脏区重绘 脏区 Dirty Regi ...
- WPF界面控件Telerik UI for WPF发布R2 2019 SP1|实现新的属性
Telerik UI for WPF拥有超过100个控件来创建美观.高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序.UI for WPF支持MVVM.触摸等,创建的应用程序可靠且结构良 ...
- UI控件Telerik UI for WPF发布R2 2019|附下载
Telerik UI for WPF拥有超过100个控件来创建美观.高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序.UI for WPF支持MVVM.触摸等,创建的应用程序可靠且结构良 ...
- 高级UI晋升之View渲染机制(二)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...
- JS动态修改页面EasyUI datebox不生效、EasyUI动态添加Class、EasyUI动态渲染解析解决方案
这是个小菜在实际工作中遇到的问题,相信很多EasyUI新手很可能也遇到这样的问题,因此小菜觉得有必要拿出来分享一下. 这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$( ...
- js动态修改Easyui元素不生效,EasyUI动态渲染解析解决方案
easyui的渲染是在在网页加载完成后,相当于在$(document).ready()事件中,对整个网页进行了一次扫描,发现某个input标签含有easyui的属性,就在相应的地方进行ui的修改.因此 ...
- vue + element ui 实现实现动态渲染表格
前言:之前需要做一个页面,能够通过表名动态渲染出不同的表格,这里记录一下.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9786326.html 网站地址:我的 ...
随机推荐
- JavaCV的摄像头实战之二:本地窗口预览
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 安卓开发常见Bug-setContentView(R.layout.....)报错
这是安卓开发的常见错误,当你在引用或者复制别人的Layout xml文件时需要在AndroidManifest.xml中添加东西 需要将图中的activity android:name添加进去,否则是 ...
- 【转】MySql根据经纬度获取附近的商家
创建geo表 create table geo( geo_id INT NOT NULL AUTO_INCREMENT, lng float NOT NULL, lat float NOT NULL, ...
- Ubuntu16.04的PHP开发环境配置
\3c a { text-decoration: none } 自从换了php开发之后发现还是开源语言才是长久之道,开发环境搭建方便,支持的平台也多,性能也好,考虑到这些,其他一些不如意也就不足为虑了 ...
- 如何清除项目git版本控制信息
首先进入项目目录下 邮件打开 git bash here 执行命令 find . -name ".git" | xargs rm -rf 就清除了git版本控制信息
- 内联函数 在ios中的运用 --黄仁斌
定义: 有函数的结构,但不具备函数的性质,类似于宏替换.代码中使用inline定义,能否形成内联函数,还要看编译器对内联函数体内部的定义的具体处理.产生的动机: 消除函数调用产生的开销 ...
- iptables防火墙 (纸是包不住火的,得用水泥)
iptables防火墙 1.Linux防火墙基础 2.编写防火墙规则 1.Linux防火墙基础 iptables概述: Linux 系统的防火墙: IP信息包过滤系统,它实际上由两个组件netfilt ...
- fuzz——AFL基础使用方法
最近打 ctf 的时候感觉有点遇到瓶颈,就来 fuzz 这块看看. AFL 全称为 American huzzy loop,是 Fuzzing 最高级的测试工具之一.这个工具对有源码和无源码的二进制程 ...
- axios请求配置
全局配置示例(在js文件配置): axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common[' ...
- netty系列之:JVM中的Reference count原来netty中也有
目录 简介 ByteBuf和ReferenceCounted ByteBuf的基本使用 ByteBuf的回收 ByteBuf的衍生方法 ChannelHandler中的引用计数 内存泄露 总结 简介 ...