WinForm(七)在新线程中更新UI

在WinForm项目中,很多时候会映遇上多线程一起工作的情况,因为当前UI的更新显示,是在主线程中,一但主线程被长时运算占据后,UI就会被卡信,出现假死现像。那么就需要起一个新线程做长时运算工作,把进度或数据同步回UI线程。

以一个医保上传数据为例,功能是同步药品,器械,诊疗项目,同步完后进行验证核对。

注:为了看得清晰,各个关键控件我没有重命名

定义一个list来充当步骤和需要时间。

static List<Item> list;
private void Form1_Load(object sender, EventArgs e)
{list = new List<Item>{new Item{ Name="正在上传诊疗项目",Time=8 },new Item{ Name="正在上传器材",Time=12 },new Item{ Name="正在上传药品",Time=20 },new Item{ Name="正在核对",Time=24 },};
}

第一版:用Task.Run来启动一个新的线程,中的for循环是为了表示一个进度的...的切换,如果换成一个gif图标更佳,foreach循环是完成list中各项任务的。如果运行,你会发现,窗体上是空白的,18行的给messageLabel.Text不起作用。

private void button1_Click(object sender, EventArgs e)
{Task.Run(() =>{foreach (var item in list){var dotString = "";for (var i = 0; i < item.Time; i++){if (i % 6 == 0){dotString = ".";}else{dotString += ".";}messageLabel.Text = $"{item.Name}{dotString}";SpinWait.SpinUntil(() => false, 300);}}MessageBox.Show("完成医保所有数据同步");});
}

第二版:为了更新UI线程,在新线程中用this.Invoke来更新UI上控件的值,如18行。这回没有什么问题了,UI也能即时更新,看上去很完美。

private void button2_Click(object sender, EventArgs e)
{Task.Run(() =>{foreach (var item in list){var dotString = "";for (var i = 0; i < item.Time; i++){if (i % 6 == 0){dotString = ".";}else{dotString += ".";}this.Invoke(() =>{messageLabel.Text = $"{item.Name}{dotString}";});SpinWait.SpinUntil(() => false, 300);}}MessageBox.Show("完成医保所有数据同步");});
}

其实这背后是有异常的(有可能会在vs中报出来),因为当你关闭窗体时,18行的this已经不存在了,但访问this.Invoke在新的线程中,新线程本身并没有关掉,这时就会报找不到实例,有可能你运行起来并不会发现异常,这是因为主线程关闭后,所有创建的子线程都会关闭的,为了验证,你可以5行前面加一个try,在catch中把异常内容写在一个日志文件中。

我的结果是:

Cannot access a disposed object.
Object name: 'Form1'.

第三版:发现问题,那就解决吧(有可能你觉得无所谓,窗体都关闭了,没报异常,看不出来。确实,如果你觉得无所谓,那就无所谓,这里只是来说明技术点的,不是来说服想法的),通过一个mark标志,在关闭窗体时,拦截一下,把子线程关闭,然后再把主窗体关闭,这样就没有问题了,自己起的线程,自己要关掉。

static bool mark = true;
private void startButton_Click(object sender, EventArgs e)
{Task.Run(() =>{foreach (var item in list){if (mark == false){break;}var dotString = "";for (var i = 0; i < item.Time; i++){if (mark == false){break;}if (i % 6 == 0){dotString = ".";}else{dotString += ".";}this.Invoke(() =>{messageLabel.Text = $"{item.Name}{dotString}";});SpinWait.SpinUntil(() => false, 300);}}if (mark){mark = false;MessageBox.Show("完成医保所有数据同步");}else{this.Invoke(() =>{this.Close();});}});
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{if (mark){e.Cancel = true;mark = false;}
}

线程是个大话题,这只是简单的线程协同,两个线程没有深度协同。通过这个例子,三个版本,一步一步来满足功能,提升健壮性和安全性,我们们可以得出,做了一个功能,是需要下功夫的,不但要知其然,还要知其所以然。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283639.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多种方法实现自适应布局

最近切了几个手机端的网页&#xff0c;第一次切的是美团的首页&#xff0c;为了自适应不同的手机分辨率&#xff0c;需要用到自适应布局&#xff0c;切图的时候是用的第一中方法&#xff0c;用到了定位&#xff0c;后来查找了一些其他方法&#xff0c;现在就介绍几种自适应布局…

hivesql优化的深入解析

转载&#xff1a;https://www.csdn.net/article/2015-01-13/2823530 一个Hive查询生成多个Map Reduce Job&#xff0c;一个Map Reduce Job又有Map&#xff0c;Reduce&#xff0c;Spill&#xff0c;Shuffle&#xff0c;Sort等多个阶段&#xff0c;所以针对Hive查询的优化可以大致…

如何用一行 CSS 实现 10 种现代布局

现代 CSS 布局使开发人员只需按几下键就可以编写十分有意义且强大的样式规则。上面的讨论和接下来的帖文研究了 10 种强大的 CSS 布局&#xff0c;它们实现了一些非凡的工作。 01. 超级居中&#xff1a;place-items: center 对于第一个“单行”布局&#xff0c;让我们解决所有 …

谈谈我对MVC的View层实现的理解

谈谈我对MVC的View层实现的理解 MVC框架可以把应用清晰明了地分为三个部分&#xff1a;Model层–数据层&#xff0c;View层–视图层&#xff0c;Controller–逻辑层&#xff0c;Model层负责整合数据&#xff0c;View层负责页面渲染&#xff0c;Controller层负责实现业务逻辑。 …

在.NET 6.0中使用不同的托管模型

本章是《定制ASP NET 6.0框架系列文章》的第六篇。在本章中&#xff0c;我们将讨论如何在ASP NET 6.0中自定义托管宿主。比如&#xff0c;托管选项和不同类型的托管&#xff0c;并了解一下IIS上的托管。限于篇幅&#xff0c;本章只是一个抛砖迎玉。本章涵盖主题包括&#xff1a…

Supplemental Logging

Supplemental Logging分为两种&#xff1a;Database-Level Supplemental Logging和Table-Level Supplemental Logging&#xff0c;即数据库级别和表级别。下面我们来看看Oracle官方文档对其的介绍和说明&#xff0c;引自 http://docs.oracle.com/cd/E11882_01/server.112/e2249…

TypeScript 与 JavaScript 的区别

TypeScript 是 JavaScript 的一个超集&#xff0c;支持 ECMAScript 6 标准&#xff08;ES6 教程&#xff09;。TypeScript 由微软开发的自由和开源的编程语言。TypeScript 设计目标是开发大型应用&#xff0c;它可以编译成纯 JavaScript&#xff0c;编译出来的 JavaScript 可以…

【caffe】create_cifar10.sh在windows下解决方案

tags caffe python windows下配置caffe后&#xff0c;create_cifar10.sh无法执行&#xff0c;因为是shell脚本。那就看懂脚本意思&#xff0c;用python重写一个&#xff1a; # create_cifar10.py # by ChrisZZimport os import shutilEXAMPLE"examples\\cifar10" DAT…

IO 和NIO的区别

1.IO和NIO的区别 NIO就是New IO在JDK1.4中引入。 IO和NIO有相同的作用和目的&#xff0c;但实现方式不同&#xff0c;NIO主要用到的是块&#xff0c;所以NIO的效率要比IO快不少。 在Java API中提供了两套NIO&#xff0c;一套针对标准输入输出NIO&#xff0c;另一套就是网络编程…

PerfView专题 (第四篇):如何寻找 C# 中程序集泄漏

一&#xff1a;背景 前两篇我们都聊到了非托管内存泄漏&#xff0c;一个是 HeapAlloc &#xff0c;一个是 VirtualAlloc&#xff0c;除了这两种泄漏之外还存在其他渠道的内存泄漏&#xff0c;比如程序集泄漏&#xff0c;这一篇我们就来聊一聊。二&#xff1a;程序集也会泄漏&am…

站立会议第九天

1.站立会议内容 昨天我们成功的将图片插进去了&#xff0c;在这里&#xff0c;图片是使用的png格式&#xff0c;长知识了。我们今天要继续把界面再优化一下。 照片&#xff1a; 2.任务展板 3.燃尽图 转载于:https://www.cnblogs.com/bk1246788/p/6852935.html

Android TimeAnimator

TimeAnimator:提供了一个简单的回调机制&#xff0c;通过 TimeAnimator.TimeListener&#xff0c;在动画的每一帧处通知你。这个动画器没有时间&#xff0c;插值或是对象值设定。回调监听器为每一帧动画接受信息&#xff0c;包括总运行时间和从前一帧到现在的运行时间. 相关方法…

学习nginx 下面只是简单的配置文件

2019独角兽企业重金招聘Python工程师标准>>> #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } …

实现城市治理一网统管,必须这 4 个关键技术

导读&#xff1a;要实现城市治理一网统管&#xff0c;必须具备以下四个关键技术&#xff1a;城市状态一网感知、城市数据一网共享、信息流转三屏联动、虚实映射数字孪生。 作者&#xff1a;郑宇 来源&#xff1a;大数据DT&#xff08;ID&#xff1a;hzdashuju&#xff09; 01…

基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

windbg工具安装配置及dump抓取

安装与配置windbg 安装与配置windbg的symbol(符号) 第一步 下载WinDBG&#xff0c; 第二步 双击下载的文件安装windbg.安装时注意记住安装到那里了. 第三步 windbg访问符号需要两个文件(SYMSRV.DLL 和 SYMSTORE.EXE)所以在环境变量path中将windbg安装目录添加进去&#xff0c;这…

三种Oracle RMAN备份加密策略(下)

说明&#xff1a;本篇参考eygle老师的作品《Oracle DBA手记4&#xff1a;数据安全警示录》&#xff0c;特此表示感谢。 3 、Oracle Wallet加密策略Oracle Wallet是一种加密安全策略&#xff0c;过去我们在TDE&#xff08;Oracle透明加密&#xff09;部分研究过这个组件。简单的…

实现生成订单30分钟未支付,则自动取消

目录 了解需求 方案 1&#xff1a;数据库轮询 思路 实现 优点 缺点 方案 2&#xff1a;JDK 的延迟队列 思路 实现 优点 缺点 方案 3&#xff1a;时间轮算法 思路 实现 优点 缺点 方案 4&#xff1a;redis 缓存 思路一 实现一 解决方案 思路二 实现二 优…

Oracle树形结构查询之prior的理解

--1 建表 create table 宇宙( 行星等级 number ,行星名称 varchar2(50) ,上级行星等级 number); --2 数据准备 insert into 宇宙 (行星等级, 行星名称, 上级行星等级)values (1, 地球, 2); insert into 宇宙 (行星等级, 行星名称, 上级行星等级)values (2, 太阳, 3); insert in…

CA周记-.NET MAUI in GCR 月报(2022年8月)

.NET MAUI 正式版本发布已经三个月了&#xff0c;有小伙伴希望我们有一些关于 .NET MAUI 相关的本地化内容以及开源项目介绍&#xff0c;接下来从8月开始&#xff0c;我希望用月报的形式和大家分享 .NET MAUI 在中国的活动&#xff0c;学习资源&#xff0c;优秀的开源项目&…