【WinForm.NET开发】实现使用后台操作的窗体
本文内容
- 创建使用后台操作的窗体
- 使用设计器创建 BackgroundWorker
- 添加异步事件处理程序
- 添加进度报告和取消支持
- Checkpoint
如果某项操作需要很长的时间才能完成,并且不希望用户界面 (UI) 停止响应或阻塞,则可以使用 BackgroundWorker 类在另一个线程上执行此操作。
本演练演示如何使用 BackgroundWorker 类“在后台”执行耗时的计算,同时用户界面保持响应。 演练时,将有一个异步计算 Fibonacci 数列的应用程序。 即使计算大型 Fibonacci 数列需要花费大量时间,但主 UI 线程不会被这种延时中断,并且在计算期间窗体仍会响应。
本演练涉及以下任务:
-
创建基于 Windows 的应用程序
-
在窗体中创建 BackgroundWorker
-
添加异步事件处理程序
-
添加进度报告和取消支持
1、创建使用后台操作的窗体
-
在 Visual Studio 中,创建一个名为
BackgroundWorkerExample的基于 Windows 的应用程序项目(“文件”>“新建”>“项目”>“Visual C#”或“Visual Basic”>“经典桌面”>“Windows 窗体应用程序”)。 -
在“解决方案资源管理器”中,右键单击“Form1”,然后从快捷菜单中选择“重命名”。 将文件名更改为
FibonacciCalculator。 询问是否希望重命名对代码元素“”的所有引用时,单击“是”Form1按钮。 -
从“工具箱”将 NumericUpDown 控件拖到窗体上。 将 Minimum 属性设置为
1,将 Maximum 属性设置为91。 -
向窗体添加两个 Button 控件。
-
重命名第一个 Button 控件
startAsyncButton,并将 Text 属性设置为Start Async。 重命名第二个 Button 控件cancelAsyncButton,并将 Text 属性设置为Cancel Async。 将它的 Enabled 属性设置为false。 -
为两个 Button 控件的 Click 事件创建一个事件处理程序。
-
从“工具箱”将 Label 控件拖到窗体上,然后将其重命名为
resultLabel。 -
从“工具箱”将 ProgressBar 控件拖到窗体上。
2、使用设计器创建 BackgroundWorker
可以使用“Windows 窗体设计器”为异步操作创建 BackgroundWorker。
从“工具箱”的“组件”选项卡中,将 BackgroundWorker 拖到窗体上。
3、添加异步事件处理程序
现在已准备好为 BackgroundWorker 组件的异步事件添加事件处理程序。 这些事件处理程序将调用在后台运行的计算 Fibonacci 数列的耗时操作。
-
在“属性”窗口中的 BackgroundWorker 组件仍处于选中状态时,单击“事件”按钮。 双击 DoWork 和 RunWorkerCompleted 事件以创建事件处理程序。
-
在窗体中新建一个名为
ComputeFibonacci的新方法。 此方法完成实际的工作,并在后台运行。 这些代码演示了 Fibonacci 算法的递归实现,这种算法的效率非常低,对于较大的数值花费的时间按指数增长。 在这里使用是出于演示的目的,为了说明在应用程序中某项操作可能带来长时间的延迟。// This is the method that does the actual work. For this // example, it computes a Fibonacci number and // reports progress as it does its work. long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e) {// The parameter n must be >= 0 and <= 91.// Fib(n), with n > 91, overflows a long.if ((n < 0) || (n > 91)){throw new ArgumentException("value must be >= 0 and <= 91", "n");}long result = 0;// Abort the operation if the user has canceled.// Note that a call to CancelAsync may have set// CancellationPending to true just after the// last invocation of this method exits, so this// code will not have the opportunity to set the// DoWorkEventArgs.Cancel flag to true. This means// that RunWorkerCompletedEventArgs.Cancelled will// not be set to true in your RunWorkerCompleted// event handler. This is a race condition.if (worker.CancellationPending){e.Cancel = true;}else{if (n < 2){result = 1;}else{result = ComputeFibonacci(n - 1, worker, e) +ComputeFibonacci(n - 2, worker, e);}// Report progress as a percentage of the total task.int percentComplete =(int)((float)n / (float)numberToCompute * 100);if (percentComplete > highestPercentageReached){highestPercentageReached = percentComplete;worker.ReportProgress(percentComplete);}}return result; } -
在 DoWork 事件处理程序中,添加对
ComputeFibonacci方法的调用。 从 DoWorkEventArgs 的 Argument 属性中获取ComputeFibonacci的第一个参数。 稍后将 BackgroundWorker 和 DoWorkEventArgs 参数用于进度报告和取消支持。 将ComputeFibonacci的返回值分配给 DoWorkEventArgs 的 Result 属性。 此结果将可供 RunWorkerCompleted 事件处理程序使用。备注
DoWork 事件处理程序不直接引用
backgroundWorker1实例变量,因为这将会使此事件处理程序和某个特定的 BackgroundWorker 实例耦合。 相反,引发此事件的 BackgroundWorker 引用将从sender参数恢复。 当窗体承载多个 BackgroundWorker 时这非常重要。 在 DoWork 事件处理程序中不操作任何用户界面对象也非常重要。 而应该通过 BackgroundWorker 事件与用户界面进行通信。// This event handler is where the actual, // potentially time-consuming work is done. private void backgroundWorker1_DoWork(object sender,DoWorkEventArgs e) {// Get the BackgroundWorker that raised this event.BackgroundWorker worker = sender as BackgroundWorker;// Assign the result of the computation// to the Result property of the DoWorkEventArgs// object. This is will be available to the// RunWorkerCompleted eventhandler.e.Result = ComputeFibonacci((int)e.Argument, worker, e); } -
在
startAsyncButton控件的 Click 事件处理程序中,添加启动异步操作的代码。private void startAsyncButton_Click(System.Object sender,System.EventArgs e) {// Reset the text in the result label.resultLabel.Text = String.Empty;// Disable the UpDown control until// the asynchronous operation is done.this.numericUpDown1.Enabled = false;// Disable the Start button until// the asynchronous operation is done.this.startAsyncButton.Enabled = false;// Enable the Cancel button while// the asynchronous operation runs.this.cancelAsyncButton.Enabled = true;// Get the value from the UpDown control.numberToCompute = (int)numericUpDown1.Value;// Reset the variable for percentage tracking.highestPercentageReached = 0;// Start the asynchronous operation.backgroundWorker1.RunWorkerAsync(numberToCompute); } -
在 RunWorkerCompleted 事件处理程序中,将计算结果分配给
resultLabel控件。// This event handler deals with the results of the // background operation. private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {// First, handle the case where an exception was thrown.if (e.Error != null){MessageBox.Show(e.Error.Message);}else if (e.Cancelled){// Next, handle the case where the user canceled// the operation.// Note that due to a race condition in// the DoWork event handler, the Cancelled// flag may not have been set, even though// CancelAsync was called.resultLabel.Text = "Canceled";}else{// Finally, handle the case where the operation// succeeded.resultLabel.Text = e.Result.ToString();}// Enable the UpDown control.this.numericUpDown1.Enabled = true;// Enable the Start button.startAsyncButton.Enabled = true;// Disable the Cancel button.cancelAsyncButton.Enabled = false; }
4、添加进度报告和取消支持
由于异步操作将会花费很长的时间,因此通常希望向用户报告进度并允许用户取消操作。 BackgroundWorker 类提供一个在后台操作进行时允许发送进度消息的事件。 它还提供允许辅助代码检测对 CancelAsync 的调用并中断自身的标记。
实现进度报告
-
在“属性”窗口中,选择
backgroundWorker1。 将 WorkerReportsProgress 和 WorkerSupportsCancellation 属性设置为true。 -
在
FibonacciCalculator窗体中声明两个变量。 这将用于跟踪进度。private int numberToCompute = 0; private int highestPercentageReached = 0; -
为 ProgressChanged 事件添加事件处理程序。 在 ProgressChanged 事件处理程序中,使用 ProgressChangedEventArgs 参数的 ProgressPercentage 属性更新 ProgressBar。
// This event handler updates the progress bar. private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e) {this.progressBar1.Value = e.ProgressPercentage; }
实现取消支持
-
在
cancelAsyncButton控件的 Click 事件处理程序中,添加取消异步操作的代码。private void cancelAsyncButton_Click(System.Object sender,System.EventArgs e) {// Cancel the asynchronous operation.this.backgroundWorker1.CancelAsync();// Disable the Cancel button.cancelAsyncButton.Enabled = false; } -
下面的
ComputeFibonacci方法中的代码片段可报告进程并支持取消。if (worker.CancellationPending) {e.Cancel = true; }// Report progress as a percentage of the total task. int percentComplete =(int)((float)n / (float)numberToCompute * 100); if (percentComplete > highestPercentageReached) {highestPercentageReached = percentComplete;worker.ReportProgress(percentComplete); }
5、Checkpoint
此时,可以编译并运行 Fibonacci 计算器应用程序。
按 F5 编译并运行应用程序。
在后台运行计算的同时,将会看到 ProgressBar 显示完成计算的进度。 也可以取消挂起的操作。
对于较小数值,计算应非常快,但对于较大数值,将看到明显的延时。 如果输入 30 或更大的值,应看到有几秒钟的延时,这取决于计算机的速度。 对于大于 40 的值,完成计算可能要花费数分钟或数小时。 在计算器计算较大的 Fibonacci 数列时,注意可以自由地移动窗体、最小化、最大化甚至关闭窗体。 这是因为主 UI 线程不会等待计算完成。
相关文章:
【WinForm.NET开发】实现使用后台操作的窗体
本文内容 创建使用后台操作的窗体使用设计器创建 BackgroundWorker添加异步事件处理程序添加进度报告和取消支持Checkpoint 如果某项操作需要很长的时间才能完成,并且不希望用户界面 (UI) 停止响应或阻塞,则可以使用 BackgroundWorker 类在另一个线程上…...
【操作系统和计网从入门到深入】(四)基础IO和文件系统
前言 这个专栏其实是博主在复习操作系统和计算机网络时候的笔记,所以如果是博主比较熟悉的知识点,博主可能就直接跳过了,但是所有重要的知识点,在这个专栏里面都会提到!而且我也一定会保证这个专栏知识点的完整性&…...
四.Winform使用Webview2加载本地HTML页面并互相通信
Winform使用Webview2加载本地HTML页面并互相通信 往期目录本节目标核心代码实现HTML代码实现的窗体Demo2代码效果图 往期目录 往期相关文章目录 专栏目录 本节目标 实现刷新按钮点击 C# winform按钮可以调用C# winform代码显示到html上点击HTML按钮可以调用C# winform代码更…...
如何有效清理您的Python环境:清除Pip缓存
Python是一个广泛使用的高级编程语言,以其强大的库和框架而闻名。然而,随着时间的推移和不断安装新的包,Python环境可能会变得混乱不堪,尤其是pip缓存可能占用大量的磁盘空间。本文将向您展示如何有效地清理pip缓存,保…...
Jira 母公司全面停服 Server 产品,用户如何迁移至极狐GitLab
Jira 母公司即将全面停服旗下部分 Server 端产品的销售和服务支持! Jira 母公司 Atlassian 在几年前确定了公司的战略为“全面上云”,为此做出了停止 Server 产品的销售和支持。整个时间线从 2021 年 2 月 2 日开始,直到今年 2 月 15 日&…...
Docker安装配置OnlyOffice
OnlyOffice 是一款强大的办公套件,你可以通过 Docker 轻松安装和部署它。本文将指导你完成安装过程。 步骤 1:拉取 OnlyOffice Docker 镜像 首先,使用以下命令从 Docker Hub 拉取 OnlyOffice Document Server 镜像: sudo docke…...
启动低轨道卫星LEO通讯产业与6G 3GPP NTN标准
通讯技术10年一个大跃进,从1990年的2G至2000年的3G网路,2010年的4G到近期2020年蓬勃发展的5G,当通讯技术迈入融合网路,当前的 5G 技术不仅可提供高频宽、低延迟,同时可针对企业与特殊需求以 5G 专网的模式提供各式服务…...
PICO Developer Center 创建和调试 ADB 命令
PICO 开发者中心概览 ADB 是一个轻量级的 Android 调试桥(Android Debug Bridge,简称 ADB),用于与 Android 设备进行通信和调试。ADB提供了许多有用的功能,使开发人员能够轻松地管理和调试设备上的应用程序。 你可以使用 PDC 工具来调试系统…...
【VRTK】【PICO】如何快速创建一个用VRTK开发的PICO项目
【背景】 每次新建一个VRTK的PICO项目总是做一些重复工作,于是就想着搞成一个基本的包,把基本的设置都放进去,今后新做项目直接导这个包就行了。 完整资源包请见本篇博客的绑定资源。 【内容简介】 这个包是我为了快速开发基于VRTK的PICO应用设置的基础项目包。每次开发…...
国产操作系统:VirtualBox安装openKylin-1.0.1虚拟机并配置网络
国产操作系统:VirtualBox安装openKylin-1.0.1虚拟机并配置网络 openKylin 操作系统目前适配支持X86、ARM、RISC-V三个架构的个人电脑、平板电脑及教育开发板,可以满足绝大多数个人用户及开发者的使用需求。适用于在VirtualBox平台上安装openKylin-1.0.1…...
本地git切换地区后,无法使用ssh访问github 22端口解决方案
问题 由于放假回家,发现之前一直使用正常的git,与github无法通讯,pull和push都无法连接。报错如下: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 原因 可能是所…...
Chat2DB:AI赋能的多数据库客户端工具,开源领航未来数据库管理
Chat2DB:开源多数据库客户端的AI革新 Chat2DB使用教程:Chat2DB使用教程_哔哩哔哩_bilibili 引言: 随着企业数据的快速膨胀,数据库管理的复杂性也在增加。此时,一个能够跨越数据库边界、并且集成先进的AI功能的工具,不…...
SQL Server修改数据字段名的方法
1. ALTER TABLE语句修改 这是一种最常用的数据库更改字段的方法,使用Alter Table语句来更改数据库字段的名称。 一般格式如下: ALTER TABLE 表名 RENAME COLUMN 原字段名 TO 新字段名; 例如,修改字段名字段名从UserName到Uname:…...
Flutter编译报错Connection timed out: connect
背景:用Android Studo 创建了Flutter项目,编译运行报错java.net.ConnectException: Connection timed out: connect 我自己的环境: windows11 Android Studio Flutter 截图如下: 将错误日志展开之后: Exception…...
PG DBA培训26:PostgreSQL运维诊断与监控分析
本课程由风哥发布的基于PostgreSQL数据库的系列课程,本课程属于PostgreSQL Diagnosis and monitoring analysis,学完本课程可以掌握PostgreSQL日常运维检查-风哥PGSQL工具箱,风哥专用PGSQL工具箱介绍,风哥专用PGSQL工具箱使用&…...
运维之道—生产环境安装Redis
目录 1.前言 2.环境准备 2.1 安装gcc依赖 3.部署安装 3.1 下载redis安装包 3.2 解压并编译安装redis 3.3 配置redis 编辑3.4 启动redis并测试 4. 总结 1.前言 大家好,运维之道的系列文章继续进行,我们今天整理的是Redis生产环境的安装,Redis的安装以及生产环境的…...
人工智能数学验证工具LEAN4【入门介绍3】乘法世界-证明乘法的所有运算律
视频链接,创作不易记得投币哦: import Game.Levels.Multiplication.L08add_mul World "Multiplication" Level 9 Title "mul_assoc" namespace MyNat Introduction " We now have enough to prove that multiplication is a…...
Armv8-M的TrustZone技术简介
TrustZone技术是适用于Armv8-M的可选安全扩展,旨在为各种嵌入式应用提供改进的系统安全基础。 TrustZone技术的概念并不新鲜。该技术已经在Arm Cortex-A系列处理器上使用了几年,现在已经扩展到Armv8-M处理器。 在high level上,TrustZone技术适用于Armv8-M的概念与Arm Cort…...
ctfshow-反序列化(web267-web270)
目录 web267 web268 web269 web270 总结 web267 页面用的什么框架不知道 看源码看一下 框架就是一种软件工具,它提供了一些基础功能和规范,可以帮助开发者更快地构建应用程序。比如Yii框架和ThinkPHP框架就是两个流行的PHP框架,它们提供…...
决策树的分类
概念 决策树是一种树形结构 树中每个内部节点表示一个特征上的判断,每个分支代表一个判断结果的输出,每个叶子节点代表一种分类结果 决策树的建立过程 1.特征选择:选取有较强分类能力的特征。 2.决策树生成:根据选择的特征生…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
