当前位置: 首页 > news >正文

【WinForm.NET开发】实现使用后台操作的窗体

本文内容

  1. 创建使用后台操作的窗体
  2. 使用设计器创建 BackgroundWorker
  3. 添加异步事件处理程序
  4. 添加进度报告和取消支持
  5. Checkpoint

如果某项操作需要很长的时间才能完成,并且不希望用户界面 (UI) 停止响应或阻塞,则可以使用 BackgroundWorker 类在另一个线程上执行此操作。

本演练演示如何使用 BackgroundWorker 类“在后台”执行耗时的计算,同时用户界面保持响应。 演练时,将有一个异步计算 Fibonacci 数列的应用程序。 即使计算大型 Fibonacci 数列需要花费大量时间,但主 UI 线程不会被这种延时中断,并且在计算期间窗体仍会响应。

本演练涉及以下任务:

  • 创建基于 Windows 的应用程序

  • 在窗体中创建 BackgroundWorker

  • 添加异步事件处理程序

  • 添加进度报告和取消支持

1、创建使用后台操作的窗体

  1. 在 Visual Studio 中,创建一个名为 BackgroundWorkerExample 的基于 Windows 的应用程序项目(“文件”>“新建”>“项目”>“Visual C#”或“Visual Basic”>“经典桌面”>“Windows 窗体应用程序”)。

  2. 在“解决方案资源管理器”中,右键单击“Form1”,然后从快捷菜单中选择“重命名”。 将文件名更改为 FibonacciCalculator。 询问是否希望重命名对代码元素“”的所有引用时,单击“是”Form1按钮。

  3. 从“工具箱”将 NumericUpDown 控件拖到窗体上。 将 Minimum 属性设置为 1,将 Maximum 属性设置为 91

  4. 向窗体添加两个 Button 控件。

  5. 重命名第一个 Button 控件 startAsyncButton,并将 Text 属性设置为 Start Async。 重命名第二个 Button 控件 cancelAsyncButton,并将 Text 属性设置为 Cancel Async。 将它的 Enabled 属性设置为 false

  6. 为两个 Button 控件的 Click 事件创建一个事件处理程序。 

  7. 从“工具箱”将 Label 控件拖到窗体上,然后将其重命名为 resultLabel

  8. 从“工具箱”将 ProgressBar 控件拖到窗体上。

2、使用设计器创建 BackgroundWorker

可以使用“Windows 窗体设计器”为异步操作创建 BackgroundWorker。

从“工具箱”的“组件”选项卡中,将 BackgroundWorker 拖到窗体上。

3、添加异步事件处理程序

现在已准备好为 BackgroundWorker 组件的异步事件添加事件处理程序。 这些事件处理程序将调用在后台运行的计算 Fibonacci 数列的耗时操作。

  1. 在“属性”窗口中的 BackgroundWorker 组件仍处于选中状态时,单击“事件”按钮。 双击 DoWork 和 RunWorkerCompleted 事件以创建事件处理程序。 

  2. 在窗体中新建一个名为 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;
    }
    
  3. 在 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);
    }
    
  4. 在 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);
    }
    
  5. 在 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 的调用并中断自身的标记。

实现进度报告

  1. 在“属性”窗口中,选择 backgroundWorker1。 将 WorkerReportsProgress 和 WorkerSupportsCancellation 属性设置为 true

  2. 在 FibonacciCalculator 窗体中声明两个变量。 这将用于跟踪进度。

    private int numberToCompute = 0;
    private int highestPercentageReached = 0;
    
  3. 为 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;
    }
    

实现取消支持

  1. 在 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;
    }
    
  2. 下面的 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 如果某项操作需要很长的时间才能完成&#xff0c;并且不希望用户界面 (UI) 停止响应或阻塞&#xff0c;则可以使用 BackgroundWorker 类在另一个线程上…...

【操作系统和计网从入门到深入】(四)基础IO和文件系统

前言 这个专栏其实是博主在复习操作系统和计算机网络时候的笔记&#xff0c;所以如果是博主比较熟悉的知识点&#xff0c;博主可能就直接跳过了&#xff0c;但是所有重要的知识点&#xff0c;在这个专栏里面都会提到&#xff01;而且我也一定会保证这个专栏知识点的完整性&…...

四.Winform使用Webview2加载本地HTML页面并互相通信

Winform使用Webview2加载本地HTML页面并互相通信 往期目录本节目标核心代码实现HTML代码实现的窗体Demo2代码效果图 往期目录 往期相关文章目录 专栏目录 本节目标 实现刷新按钮点击 C# winform按钮可以调用C# winform代码显示到html上点击HTML按钮可以调用C# winform代码更…...

如何有效清理您的Python环境:清除Pip缓存

Python是一个广泛使用的高级编程语言&#xff0c;以其强大的库和框架而闻名。然而&#xff0c;随着时间的推移和不断安装新的包&#xff0c;Python环境可能会变得混乱不堪&#xff0c;尤其是pip缓存可能占用大量的磁盘空间。本文将向您展示如何有效地清理pip缓存&#xff0c;保…...

Jira 母公司全面停服 Server 产品,用户如何迁移至极狐GitLab

Jira 母公司即将全面停服旗下部分 Server 端产品的销售和服务支持&#xff01; Jira 母公司 Atlassian 在几年前确定了公司的战略为“全面上云”&#xff0c;为此做出了停止 Server 产品的销售和支持。整个时间线从 2021 年 2 月 2 日开始&#xff0c;直到今年 2 月 15 日&…...

Docker安装配置OnlyOffice

OnlyOffice 是一款强大的办公套件&#xff0c;你可以通过 Docker 轻松安装和部署它。本文将指导你完成安装过程。 步骤 1&#xff1a;拉取 OnlyOffice Docker 镜像 首先&#xff0c;使用以下命令从 Docker Hub 拉取 OnlyOffice Document Server 镜像&#xff1a; sudo docke…...

启动低轨道卫星LEO通讯产业与6G 3GPP NTN标准

通讯技术10年一个大跃进&#xff0c;从1990年的2G至2000年的3G网路&#xff0c;2010年的4G到近期2020年蓬勃发展的5G&#xff0c;当通讯技术迈入融合网路&#xff0c;当前的 5G 技术不仅可提供高频宽、低延迟&#xff0c;同时可针对企业与特殊需求以 5G 专网的模式提供各式服务…...

PICO Developer Center 创建和调试 ADB 命令

PICO 开发者中心概览 ADB 是一个轻量级的 Android 调试桥(Android Debug Bridge&#xff0c;简称 ADB)&#xff0c;用于与 Android 设备进行通信和调试。ADB提供了许多有用的功能&#xff0c;使开发人员能够轻松地管理和调试设备上的应用程序。 你可以使用 PDC 工具来调试系统…...

【VRTK】【PICO】如何快速创建一个用VRTK开发的PICO项目

【背景】 每次新建一个VRTK的PICO项目总是做一些重复工作,于是就想着搞成一个基本的包,把基本的设置都放进去,今后新做项目直接导这个包就行了。 完整资源包请见本篇博客的绑定资源。 【内容简介】 这个包是我为了快速开发基于VRTK的PICO应用设置的基础项目包。每次开发…...

国产操作系统:VirtualBox安装openKylin-1.0.1虚拟机并配置网络

国产操作系统&#xff1a;VirtualBox安装openKylin-1.0.1虚拟机并配置网络 openKylin 操作系统目前适配支持X86、ARM、RISC-V三个架构的个人电脑、平板电脑及教育开发板&#xff0c;可以满足绝大多数个人用户及开发者的使用需求。适用于在VirtualBox平台上安装openKylin-1.0.1…...

本地git切换地区后,无法使用ssh访问github 22端口解决方案

问题 由于放假回家&#xff0c;发现之前一直使用正常的git&#xff0c;与github无法通讯&#xff0c;pull和push都无法连接。报错如下&#xff1a; connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 原因 可能是所…...

Chat2DB:AI赋能的多数据库客户端工具,开源领航未来数据库管理

Chat2DB&#xff1a;开源多数据库客户端的AI革新 Chat2DB使用教程:Chat2DB使用教程_哔哩哔哩_bilibili 引言&#xff1a; 随着企业数据的快速膨胀&#xff0c;数据库管理的复杂性也在增加。此时&#xff0c;一个能够跨越数据库边界、并且集成先进的AI功能的工具&#xff0c;不…...

SQL Server修改数据字段名的方法

1. ALTER TABLE语句修改 这是一种最常用的数据库更改字段的方法&#xff0c;使用Alter Table语句来更改数据库字段的名称。 一般格式如下&#xff1a; ALTER TABLE 表名 RENAME COLUMN 原字段名 TO 新字段名; 例如&#xff0c;修改字段名字段名从UserName到Uname&#xff1a;…...

Flutter编译报错Connection timed out: connect

背景&#xff1a;用Android Studo 创建了Flutter项目&#xff0c;编译运行报错java.net.ConnectException: Connection timed out: connect 我自己的环境&#xff1a; windows11 Android Studio Flutter 截图如下&#xff1a; 将错误日志展开之后&#xff1a; Exception…...

PG DBA培训26:PostgreSQL运维诊断与监控分析

本课程由风哥发布的基于PostgreSQL数据库的系列课程&#xff0c;本课程属于PostgreSQL Diagnosis and monitoring analysis&#xff0c;学完本课程可以掌握PostgreSQL日常运维检查-风哥PGSQL工具箱&#xff0c;风哥专用PGSQL工具箱介绍&#xff0c;风哥专用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】乘法世界-证明乘法的所有运算律

视频链接&#xff0c;创作不易记得投币哦&#xff1a; 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 页面用的什么框架不知道 看源码看一下 框架就是一种软件工具&#xff0c;它提供了一些基础功能和规范&#xff0c;可以帮助开发者更快地构建应用程序。比如Yii框架和ThinkPHP框架就是两个流行的PHP框架&#xff0c;它们提供…...

决策树的分类

概念 决策树是一种树形结构 树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果 决策树的建立过程 1.特征选择&#xff1a;选取有较强分类能力的特征。 2.决策树生成&#xff1a;根据选择的特征生…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 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 适用场…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

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 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...