Winform-耗时操作导致界面渲染滞后
原因:
某些耗时操作阻塞了主线程。
理解上述原因,需先搞清楚Winform线程机制。主要有以下2点特性:1.单线程模型;2.依赖消息循环。
1.单线程模型
Winform 默认是单线程。通常,所有的UI操作,包括控件更新、事件处理,都由主线程管理(也就是UI线程)。
任何在事件处理程序中运行的代码都会占用主线程。如果某个事件中有耗时很多的操作,就会阻塞线程。比如有时PictureBox.Image的显示会滞后。
下面代码中,pictureBox1的显示会有滞后。背后的工作原理是:
“pictureBox1.Image = image0”运行完成后,系统只是将 pictureBox1 的 Image 属性更新,但不会立即触发控件绘制。(实际的绘制操作是由消息循环处理的,在 WM_PAINT 消息中完成)
pictureBox1的属性设置之后,如果紧接着有耗时操作占用UI线程,就会导致WM_PAINT无法及时处理,所以不能及时绘制。
最佳解决办法:
避免在 UI 线程执行耗时任务。将耗时任务移到后台线程,可以确保 UI 线程始终空闲以处理消息循环,比如使用 Task.Run 或 async/await。
private void button2_Click(object sender, EventArgs e)
{
using (var session = new InferenceSession(_modelPath))
{
...... // 无关代码
Bitmap image0 = new Bitmap(_imagePath);
pictureBox1.Image = image0;
// 以下是某耗时操作
DenseTensor<float> inputTensor = PreprocessImage(image0);
......
}
}
补充一点:只有主线程可以访问或更新控件;如果要从其他线程访问、更新控件,要使用特定的线程间通讯,必须使用 Control.Invoke 或 Control.BeginInvoke 方法将操作封送到 UI 线程执行。如果在后台线程中得到某个变量,需要渲染到主界面,就需要用到Control.Invoke等方法。
2.依赖消息循环
UI线程依赖消息循环(Message Loop)处理用户输入、标点击等操作和系统消息。Application.Run 启动时,UI线程进入消息循环状态,不断从消息队列中提取消息并分发到对应控件处理。上述提到的线程阻塞实际上是阻塞了消息循环。
上述2个特性明白之后,就能理解原因中提到的阻塞了。如果不理解,可以尝试在pictureBox1.Image之后跟随一个简单的耗时操作帮助理解。
Winform-耗时操作导致界面渲染滞后的更多相关文章
- C# Winform频繁刷新导致界面闪烁解决方法
C#Winform频繁刷新导致界面闪烁解决方法 一.通过对窗体和控件使用双缓冲来减少图形闪烁(当绘制图片时出现闪烁时,使用双缓冲) 对于大多数应用程序,.NET Framework 提供的默认双缓冲将 ...
- winform频繁刷新导致界面闪烁解决方法
转自龙心文 原文 winform频繁刷新导致界面闪烁解决方法 一.通过对窗体和控件使用双缓冲来减少图形闪烁(当绘制图片时出现闪烁时,使用双缓冲) 对于大多数应用程序,.NET Framework 提供 ...
- BroadCastReceiver中耗时操作导致ANR
現象:廣播接收器中進行耗時的I/O操作導致ANR. 查資料發現每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 该对 ...
- Winform 界面执行耗时操作--UI卡顿假死问题
UI卡顿假死问题 误区1:使用不同的线程操作UI控件和耗时操作(即,跨线程操作UI控件CheckForIllegalCrossThreadCalls = false;), 注意:此处只是为了记录... ...
- winform 开发中 把耗时操作 封装起来 异步执行(.net 4.0)
.先定义一个 BackgroundTask.cs 代码如下: public class BackgroundTask { private static WaitDialogForm LoadingDl ...
- 修复UE4编辑器,ClearLog操作导致的崩溃
UE4 4.24.3版本,编辑器Output Log窗口中,右键--Clear Log操作很大概率会导致编辑器奔溃:解决办法: 相关文件: Engine\Source\Developer\Output ...
- ASP.NET服务器端执行耗时操作的工作记录
公司之前有这样一个业务需求: 一名同事做出文件a0和b0,然后将a0加密为a1.b0加密为b1:再将文件a0.a1.b0和b1上传至服务器M:同时要将服务器N上的数据表添加一条记录,该记录的ID就是前 ...
- RxJava2-后台执行耗时操作,实时通知 UI 更新(一)
一.前言 接触RxJava2已经很久了,也看了网上的很多文章,发现基本都是在对RxJava的基本思想介绍之后,再去对各个操作符进行分析,但是看了之后感觉过了不久就忘了. 偶然的机会看到了开源项目 Rx ...
- AsyncTask 进行耗时操作和UI 更新
相信各位对 AsyncTask 不会陌生,虽然它有如下弊端: 1. 如果在activiy内部new 一个AsyncTask, 横竖屏切换生成一个新的activity,等结果返回时,处理不好容易出现NP ...
- WinForm查询大数据界面假死,使用异步调用解决
用DataGridView无分页绑定一个几千条数据的查询,查询的时候界面直接卡死十几秒,用户体验非常不好,因此用异步操作解决界面卡死的问题原本场景:点击[查询]后,界面直接卡死优化场景:点击[查询]后 ...
随机推荐
- 记录一个Linux代码移植到Windows平台下的Visual Studio 2022的代码编码格式的问题
一.前言 工作上与公司的前辈对接,他给了我一份在linux下面编写的代码压缩包,按照道理来说使用条件宏编译不同的windows和linux的API即可实现代码的通用.但是我在Visual Studio ...
- 成为JavaGC专家Part II — 如何监控Java垃圾回收机制
本文是成为Java GC专家系列文章的第二篇.在第一篇<深入浅出Java垃圾回收机制>中我们学习了不同GC算法的执行过程,GC是如何工作的,什么是新生代和老年代,你应该了解的JDK7中的5 ...
- go官方包依赖管理工具之mod
1.1.go mod是什么 go mod 是Golang 1.11 版本引入的官方包(package)依赖管理工具,用于解决之前没有地方记录依赖包具体版本的问题,方便依赖包的管理. 之前Golang ...
- 项目部署工具之walle
最近部署walle进行线上项目的上线发布,安装中遇到的问题,在此记录 walle(http://www.walle-web.io) git地址:https://github.com/meolu/wal ...
- AWMS(ApeosWare Management Suite)的一些配置信息
富士胶片商业创新的富士施乐打印复印一体机,一般可用被称为亚特兰大(ApeosWare Management Suite)的管理软件. Windows Server 2012 上安装的SQLServer ...
- 命令行应用开发初学者指南:脚手架篇、UI 库和交互工具
在日常的前端开发工作中,我们经常依赖各种命令行工具来提高效率和代码质量.例如,create-react-app 和 eslint 等工具不仅简化了项目的初始化过程,还能自动执行代码检查和格式化任务.当 ...
- OceanBase 的探索与实践
作者:来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题,完整的描述了 OceanBase 的实施落地, ...
- Net使用EasyNetQ简化与RabbitMQ的交互
Net使用EasyNetQ简化与RabbitMQ的交互 EasyNetQ是一个为.NET环境设计的RabbitMQ客户端API,旨在简化与RabbitMQ的交互. 关于RabbitMq的更多知识点在: ...
- 【Javaweb】【Js】【Servlet】Js与Servlet交互 - Js请求Servlet与响应Servlet
[原生JS][POST]请求和响应(一) 虽然效率有点低,但是作为初学者,可以先看看这个,然后再去看后面用Json处理. XMLHttpRequest介绍 XMLHttpRequest 对象用于在后台 ...
- Linux下如何获取CPU内存等硬件信息
前言 在linux环境下,我们有时候需要写一些有关服务器配置信息的文档,这时候,如果我们本身没有这些这些服务器的购置信息,就需要借助命令查询出来,然后汇总到一个表格里,主要用于一些文档需要. Linu ...