众所周知, 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 大量渲染的解决方案的更多相关文章

  1. 美团开源Graver框架:用“雕刻”诠释iOS端UI界面的高效渲染

    Graver 是一款高效的 UI 渲染框架,它以更低的资源消耗来构建十分流畅的 UI 界面.Graver 独创性的采用了基于绘制的视觉元素分解方式来构建界面,得益于此,该框架能让 UI 渲染过程变得更 ...

  2. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  3. 通过分析 WPF 的渲染脏区优化渲染性能

    原文:通过分析 WPF 的渲染脏区优化渲染性能 本文介绍通过发现渲染脏区来提高渲染性能. 本文内容 脏区 Dirty Region WPF 性能套件 脏区监视 优化脏区重绘 脏区 Dirty Regi ...

  4. WPF界面控件Telerik UI for WPF发布R2 2019 SP1|实现新的属性

    Telerik UI for WPF拥有超过100个控件来创建美观.高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序.UI for WPF支持MVVM.触摸等,创建的应用程序可靠且结构良 ...

  5. UI控件Telerik UI for WPF发布R2 2019|附下载

    Telerik UI for WPF拥有超过100个控件来创建美观.高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序.UI for WPF支持MVVM.触摸等,创建的应用程序可靠且结构良 ...

  6. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

  7. JS动态修改页面EasyUI datebox不生效、EasyUI动态添加Class、EasyUI动态渲染解析解决方案

    这是个小菜在实际工作中遇到的问题,相信很多EasyUI新手很可能也遇到这样的问题,因此小菜觉得有必要拿出来分享一下. 这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$( ...

  8. js动态修改Easyui元素不生效,EasyUI动态渲染解析解决方案

    easyui的渲染是在在网页加载完成后,相当于在$(document).ready()事件中,对整个网页进行了一次扫描,发现某个input标签含有easyui的属性,就在相应的地方进行ui的修改.因此 ...

  9. vue + element ui 实现实现动态渲染表格

    前言:之前需要做一个页面,能够通过表名动态渲染出不同的表格,这里记录一下.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9786326.html 网站地址:我的 ...

随机推荐

  1. 一起看看MySQL中的隐藏列

    摘要:在mysql的多版本并发控制mvcc中,我们知道mysql中存在一些隐藏列,例如行标识.事务ID.回滚指针等,不知道大家是否和我一样好奇过,要怎样才能实际地看到这些隐藏列的值呢? 本文分享自华为 ...

  2. 关于cmake和开源项目发布的那些事(PF)

    本来是打算写一篇年终总结,随便和以往一样提一提自己的开源项目(长不大的plain framework)的一些进度,不过最近这一年对于这个项目实在是维护不多,实在难以用它作为醒目的标题.而最近由于使用了 ...

  3. 多线程(Thread类中的方法线程名称)

    1 package multithread; 2 3 /* 4 * 如何创建一个线程呢? 5 * 6 * 创建线程方式一:继承Thread类. 7 * 8 * 步骤: 9 * 1,定义一个类继承Thr ...

  4. (2)puppet单机测试命令apply

    单机测试apply命令: 以独立的方式,将清单中的配置应用于本机,也就是说,根据配置清单配置当前服务器. 1.apply这个子命令有很多选项,而我们常用的有debug.verbose.noop等,de ...

  5. python12day

    昨日回顾 可迭代对象: 可以更新迭代的实实在在的值. 内部含有'__iter__'方法. str.tuple.dict.set.range 优点:操作方法多,灵活直观 缺点:占用内存. 迭代器: 可以 ...

  6. 中文分词,自然语言处理器NLP。 六月份版本已上线。

    一,  没有对比,就没有伤害,我们分词的优势在哪里?走一波测试. 跑一下CaCl2,看看效果. 二   想要分什么词汇,自己自定义即可. 目前每个月都会出一个新的版本,主要是和金融相关的词汇. 这是6 ...

  7. Java安全之BCEL ClassLoader

    目录 Java安全之BCEL ClassLoader 写在前面 About BCEL 调试分析 食用姿势 Fuzz反序列化Gadget Fastjson BCEL Payload Thymeleaf ...

  8. CF1408G Clusterization Counting

    首先,我们需要给一个连通块找到一个直观的合法判定解. 那么我们必须以一种直观的方式将边按照权值分开,这样才能直观地判定一个合法的组. 一个常见的方式是将边从小到大依次加入进来,那么在任意时刻图上存在的 ...

  9. Android 动态申请权限问题【转】

    Android 动态申请权限问题 感谢大佬:https://www.jianshu.com/p/2324a2bdb3d4 感谢大佬:https://blog.csdn.net/weixin_42910 ...

  10. 软件版本GA、Beta、RC含义

    Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用.Beta:也是测试版,这个阶段的版本会一直加入新的功能.在Alpha版之后推出.RC:(Release Candida ...