当前位置: 首页 > 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;根据选择的特征生…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...