C# backgroundworker类(后台线程)
概念
在C#程序中,经常会有一些耗时较长的CPU密集型运算,如果直接在 UI 线程执行这样的运算就会出现UI不响应的问题。解决这类问题的主要途径是使用多线程,启动一个后台线程,把运算操作放在这个后台线程中完成。但是原生接口的线程操作有一些难度,如果要更进一步的去完成线程间的通信就会难上加难。
C#的BackgroundWorker类是一个用于简化在桌面应用程序(如Windows Forms或WPF)中执行后台任务的工具。它的主要目的是在不阻塞用户界面(UI)的情况下运行耗时操作,同时支持进度报告和任务取消。
主要作用
后台执行耗时任务
在单独的线程中运行长时间操作(如文件下载、数据处理),防止UI线程被阻塞,保持界面响应。
进度更新
允许在后台任务中报告进度(如更新进度条),并自动将更新操作同步到UI线程。
取消支持
提供机制让用户请求取消正在执行的后台任务。
完成通知
在任务完成(成功、取消或出错)后,触发事件以更新UI或处理结果。
关键成员
成员 | 类型 | 说明 |
---|---|---|
DoWork | 事件 | 后台任务逻辑:在此事件处理程序中编写耗时操作代码。此代码在后台线程执行。 |
ProgressChanged | 事件 | 进度更新:通过ReportProgress() 方法触发,用于在UI上更新进度(如进度条)。 |
RunWorkerCompleted | 事件 | 任务完成通知:在任务结束时触发,处理结果或错误。 |
RunWorkerAsync() | 方法 | 启动后台任务。 |
CancelAsync() | 方法 | 请求取消任务(需设置WorkerSupportsCancellation = true )。 |
WorkerReportsProgress | 属性 | 设置为true 以启用进度报告功能。 |
WorkerSupportsCancellation | 属性 | 设置为true 以允许任务取消。 |
典型使用场景
// 创建BackgroundWorker实例
var worker = new BackgroundWorker
{ WorkerReportsProgress = true,WorkerSupportsCancellation = true
};// 订阅事件
worker.DoWork += (sender, e) =>
{for (int i = 0; i <= 100; i++) {if (worker.CancellationPending) {e.Cancel = true;return;}// 模拟耗时操作并报告进度worker.ReportProgress(i);Thread.Sleep(50);}
};worker.ProgressChanged += (sender, e) =>
{// 更新UI进度条(自动在UI线程执行)progressBar.Value = e.ProgressPercentage;
};worker.RunWorkerCompleted += (sender, e) =>
{if (e.Cancelled) MessageBox.Show("任务已取消!");else if (e.Error != null) MessageBox.Show($"错误:{e.Error.Message}");else MessageBox.Show("任务完成!");
};// 启动任务
worker.RunWorkerAsync();
注意事项
-
跨线程访问UI
-
DoWork
事件在后台线程运行,禁止直接操作UI控件。 -
ProgressChanged
和RunWorkerCompleted
事件会自动在UI线程触发,可直接更新UI。
-
-
替代方案
现代C#更推荐使用async/await
配合Task.Run
处理异步操作,代码更简洁。但BackgroundWorker
仍适用于旧项目或需要深度集成进度/取消逻辑的场景。
与async/await对比
特性 | BackgroundWorker | async/await + Task.Run |
---|---|---|
复杂度 | 基于事件,代码分散 | 线性结构,代码更清晰 |
取消支持 | 内置CancellationPending 机制 | 通过CancellationToken 实现 |
进度报告 | 内置ReportProgress | 需自定义(如IProgress<T> 接口) |
适用场景 | 简单后台任务 | 复杂异步操作,需更高灵活性 |
总结:BackgroundWorker
是简化桌面应用后台任务处理的经典工具,适合需要快速实现进度更新和取消功能的场景。但在新项目中,可优先考虑async/await
以获得更现代的编程体验。
实例(源码)
public partial class Form2 : Form
{public BackgroundWorker worker = new BackgroundWorker();public Form2(){InitializeComponent();}private void Form2_Load(object sender, EventArgs e){// Worker 工人// Reports 报告// Progress 进度// WorkeyRepoetsProgress 是否支持BackgroundWorker报告异步任务进度的功能。worker.WorkerReportsProgress = true;// WorkerSupportsCancellation 是否支持异步取消操作worker.WorkerSupportsCancellation = true;// 三个事件// 1 DoWork: 做异步耗时的操作(调用RunWorkerAsync方法之后触发)worker.DoWork += Worker_DoWork;// 2 ProgressChange 进度发生变化的事件,WorkerReportsProgress属性true的时候触发worker.ProgressChanged += Worker_ProgressChanged;// 3 RWorkerCompleted 后台操作完成的时候触发,取消或者异常的时候都会触发worker.RunWorkerCompleted += Worker_RunWorkerCompleted;}//做异步任务的函数private void Worker_DoWork(object sender, DoWorkEventArgs e){//模拟处理超时的操作Random rnd = new Random();for (int i = 0; i < 80; i++){if (worker.CancellationPending) //判断用户是否取消了后台任务{e.Cancel = true; //取消后台任务return;}else{//耗时任务(文件读写,通讯、加载tb块)Thread.Sleep(rnd.Next(100, 1000)); //休眠100-1000ms之间,模拟耗时的//报告进度int progress = (int)Math.Round(((i + 1) / 80.0) * 100);progress = progress > 100 ? 100 : progress;worker.ReportProgress(progress);// 触发进度变化的事件}}}//加载进度的函数private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e){progressBar1.Value = e.ProgressPercentage;// 把ReportProgress(progress)函数里面的参数传递过来,取出}//后台操作处理完的函数private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){this.BackColor = Color.Red;// 后台任务执行完之后的操作}//开始异步任务的按钮private void button1_Click(object sender, EventArgs e){Console.WriteLine(worker.IsBusy);// backWrork是否是繁忙状态if (!worker.IsBusy) // 空闲状态下{worker.RunWorkerAsync();// 开始后台任务}}//取消异步任务的按钮private void button2_Click(object sender, EventArgs e){if (worker.IsBusy) //非空闲状态下取消{worker.CancelAsync();//取消后台任务}}
}
相关文章:
C# backgroundworker类(后台线程)
概念 在C#程序中,经常会有一些耗时较长的CPU密集型运算,如果直接在 UI 线程执行这样的运算就会出现UI不响应的问题。解决这类问题的主要途径是使用多线程,启动一个后台线程,把运算操作放在这个后台线程中完成。但是原生接口的线程…...
OpenAI智能体初探:使用 OpenAI Responses API 在 PDF 中实现检索增强生成(RAG)
大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。 知行合一,不写水文,喜欢可关注,分享AI算法干货、技术心得。 欢迎关注《大模型理论和实战》、《DeepSeek技术解析和实战》,一起探索技术的无限可能! 引子 在信息爆炸的时代,从大量 PDF 文档中快速准确地检索信息…...
SqlServer数据库报错紧急或可疑无法访问的修复过程,亲测有效。
当 SQL Server 数据库被标记为 SUSPECT 状态时,表示数据库可能由于事务日志损坏、数据文件丢失或其他严重问题而无法正常启动。以下是一个详细的恢复步骤,基于搜索结果中的信息和常见的最佳实践: 恢复步骤 1. 确认数据库状态 将database-n…...
12.31[net]review
复用(Multiplexing)的概念 定义:在传输层,复用是指多个应用进程可以使用同一个传输层协议(如 TCP 或 UDP)来发送数据。从应用层的角度看,不同的应用进程(如网页浏览器、邮件客户端等…...
Redis超高并发分key实现
Redis扛并发的能力是非常强的,所以高并发场景下经常会使用Redis,但是Redis单分片的写入瓶颈在2w左右,读瓶颈在10w左右,如果在超高并发下即使是集群部署Redis,单分片的Redis也是有可能扛不住的,如下图所示&a…...
Houdini学习笔记
1. Houdini中一次只能显示一个物体 如果要都显示 需要 merge 节点 粉色的是 以参考显示 2.对任意一个节点按F1 可以弹出houdini官方文档 3. 恢复视角 Space H,居中 Space G 居中选中物体...
Ubuntu 22.04使用pigz多线程快速解压/压缩文件
最近搞项目,资料太大,解压时间太久,于是想办法解决。 开贴记录。 1.安装pigz sudo apt install pigz 2.解压资料 解压命令为 tar --use-compress-programpigz -xvpf ***.tar.gz 将最后的部分***.tar.gz换成你自己的文件即可 例如 ti…...
子数组问题——动态规划
个人主页:敲上瘾-CSDN博客 动态规划 基础dp:基础dp——动态规划-CSDN博客多状态dp:多状态dp——动态规划-CSDN博客 目录 一、解题技巧 二、最大子数组和 三、乘积最大子数组 四、最长湍流子数组 五、单词拆分 一、解题技巧 区分子数组&…...
汉桑科技IPO:潜藏两大风险 公众投资者权益或受损
冰山之所以危险,是因为只有八分之一在水面上。 ——语出小说家海明威。 引 言 野村证券提供的一份报告显示,2025年前两个月,我国出口同比增长仅有2.3%,与去年四季度9.9%的增长显著下滑。与此同时,从2月1日开始&a…...
【3DGS】SuperSplat本地运行+修改监听端口+导入ply模型+修剪模型+在线渲染3DGS网站推荐
SuperSplat官网代码:https://github.com/playcanvas/supersplat 本地安装和运行 Clone the repository: git clone https://github.com/playcanvas/supersplat.git cd supersplat Install dependencies: npm install Build SuperSplat and start a local web ser…...
整数与字节序列相互转换
以下函数是用于二进制编解码的核心工具函数,实现 32/64 位整数与字节流之间的高效转换。 操作逻辑:将整数的每个字节依次写入缓冲区,从最低有效字节到最高有效字节内存布局:假设 value0x12345678,地址由低到高依次是0…...
嵌入式软件测试的东方智慧:WinAMS工具的技术哲学与实践启示——一名汽车电子工程师的七年工具演进观察
引言:在丰田精益生产线上诞生的测试哲学 2017年参与某日系车企的ECU(电子控制单元)联合开发时,我第一次在名古屋工厂见到产线旁部署的WinAMS测试站。不同于欧美工具强调的“全流程覆盖”,这个诞生于日本制造业精益文化…...
卫星遥感赋能气象服务:精准预测,智享生活
卫星遥感技术作为现代气象服务的“千里眼”和“顺风耳”,正以前所未有的精度和效率,革新着我们对天气的观测、预报与应对方式。今天,就让我们一同探索卫星遥感在气象服务中的奇妙应用。 星图云开放平台:专业气象的智慧之选 高精度…...
多个nodejs版本切换使用教程
想要多个nodejs版本来回切换TOC 先卸载本地已安装的nodejs下载安装nvm ,下载地址:https://github.com/coreybutler/nvm-windows/releases打开链接后 ,选择 nvm-setup.exe 安装,安装路径避免空格和中文(如 D:\nvm) 选择…...
Vue.js 3 的设计思路:从声明式UI到高效渲染机制
目录 一、声明式UI与虚拟DOM的灵活性 二、渲染器:虚拟DOM到真实DOM的桥梁 三、组件的本质与实现 四、编译与运行时的协同优化 五、性能与可维护性的权衡 总结 Vue.js 3 作为新一代前端框架,其设计理念在声明式UI描述、虚拟DOM优化、组件化架构…...
Python控制语句 ——break和continue
1.以下关于Python循环结构的描述中,错误的是() 。 A、break用来结束当前当次语句,但不跳出当前的循环体。 B、遍历循环中的遍历结构可以是字符串、文件、组合数据类型和range函数等。 C、Python通过for,while等保留字构建循环结构。 D、continue只结束本次循环。 答案:A。在…...
Linux websocket服务器、配网方法、QT客户端程序
一、linux websocket服务器 参考下面的代码编译和运行 websocket_for_linux: c语言实验websocket通信,含服务端和客户端示例代码 二、网络配置 Linux本地开启server和client,可正常通信。 换局域网另外一台PC后无法测试通过。 解决办法:…...
Python网络爬虫之requests库的使用方法
requests库是Python中用于发送HTTP请求的一个重要库,在实际应用中,它被广泛用于爬取网页数据、调用API接口等。本节将详细讲解requests库的使用流程,包括发送HTTP请求、携带请求参数、处理服务器响应以及错误处理,帮助读者掌握requests库的基本使用方法。 1. 使用requests库…...
一、初识Docker【安装基础案例】
开始学习docker容器技术,本文介绍如何安装docker、基本概念和一个简单的容器案例。 1. 安装docker 1.1 yum源方式安装 # step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils# Step 2: 添加软件源信息 yum-config-manager --add-repo <https://mir…...
stm32 f4 flash 调用时卡死
【HAL库】STM32F407----内部Flash的读写_stm32f407 flash-CSDN博客 参照此博客,如果调用flash 卡死的原因是谢日adress不准确,得到0x08010000 成功运行...
uv pip install -r requirements.txt-报错,python版本过低
升级Python版本(推荐) browser-use0.1.40 需要 Python ≥3.11,但你的环境是 Python 3.10.12。升级Python版本是最直接的解决方案: 安装Python 3.11: 使用 pyenv(Linux/macOS):pyenv…...
c++ 中的float和double 的区别 开发过程中使用哪个更好
在 C 中,float 和 double 都是用于表示浮点数的数据类型,但它们在精度、存储空间和性能方面有所不同。 1. float 和 double 的主要区别 特性floatdouble占用内存4 字节(32 位)8 字节(64 位)精度约 6-7 位有…...
工厂模式加策略模式 -- 具体实现
这里写目录标题 定义接口定义抽象类定义主处理器分支处理器定义工厂demo 定义接口 public interface EntityHandler extends InitializingBean {MatchContentDTO match(MatchEntityDTO matchEntityDTO);String supportEntityType(); }定义抽象类 public abstract class Abstr…...
Redis7——进阶篇(五)
前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三)Redis&#x…...
什么是全栈?
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点下班 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 📃文章前言 🔷文章均为学习工…...
vue3实现虚拟滚动Vue-Virtual-Scroller
前端优化不可不避的一谈之虚拟滚动:众所周知,滚动是直挺挺的往dom树加东西,如果滚太多滚到万级,渲染过多就会卡顿,而vue-virtual-scroll的灵活懒渲染就能解决这个问题 1,下载与配置 npm install --save v…...
Flutter Dart 运算符全面解析
引言 在 Dart 语言中,运算符是用于执行各种操作的特殊符号。这些操作可以是算术运算、逻辑运算、比较运算等。了解并熟练运用这些运算符是进行 Flutter 开发的基础。本文将详细介绍 Dart 中常见的运算符,并结合代码示例进行说明。 1. 算术运算符 算术…...
XXE-labs靶场通关攻略
1.把相关压缩包放到www根目录下 2.解压,并且把php_xxe放在www目录下 3.进行访问发现是登陆页面 4.随便试试账号密码进行抓包 5.发送到重放器,发现username是回显点 6.可以利用xxe漏洞 <?xml version"1.0"?> //xml声明不重要&#x…...
Redis 主从复制详解:实现高可用与数据备份
目录 引言 1. 什么是 Redis 主从复制? 1.1 定义 1.2 核心概念 2. Redis 主从复制的工作原理 2.1 复制流程 2.2 复制流程图 3. Redis 主从复制的配置方法 3.1 通过配置文件配置 主节点配置 从节点配置 3.2 通过命令行配置 设置从节点 取消从节点 4. Re…...
文件解析漏洞靶场通关合集
一、IIS解析漏洞 (一)iis6的目录解析漏洞(.asp目录中的所有文件都会被当做asp文件执行) 第一步:在网站根目录下创建了一个x.asp文件夹,并在文件夹中创建一个名为1.txt的文本文档 第二步:文本文档中输入<% now()%&…...
vue的 props 与 $emit 以及 provide 与 inject 的 组件之间的传值对比
好的,下面是 props 与 $emit 以及 provide 与 inject 的对比: 1. props 与 $emit props:父组件通过 props 向子组件传递数据,子组件接收后不可修改。子组件只能读取 props 传递给它的数据。如果需要修改或更新父组件的状态&#…...
数据结构——环形数组
环形数组 start 指向第一个有效元素的索引,end 指向最后一个有效元素的下一个位置索引。 注意: start是闭区间,先左移后赋值,先赋值(null)后右移;end是开区间,先赋值再右移,先左移再赋值(null…...
k8s面试题总结(十五)
1.如何使用Kubernetes进行多环境部署(如开发,测试和生产环境)? 使用命名空间(namespaces): 命名空间是用于逻辑隔离和资源分组的一种方式,可以为每个环境创建单独的命名空间。 2.使…...
深度学习项目--基于DenseNet网络的“乳腺癌图像识别”,准确率90%+,pytorch复现
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 如果说最经典的神经网络,ResNet肯定是一个,从ResNet发布后,很多人做了修改,denseNet网络无疑是最成功的…...
蓝桥杯 17110抓娃娃
问题描述 小明拿了 n 条线段练习抓娃娃。他将所有线段铺在数轴上,第 i 条线段的左端点在 li,右端点在 ri。小明用 m 个区间去框这些线段,第 i个区间的范围是 [Li, Ri]。如果一个线段有 至少一半 的长度被包含在某个区间内,…...
探索高性能AI识别和边缘计算 | NVIDIA Jetson Orin Nano 8GB 开发套件的全面测评
随着边缘计算和人工智能技术的迅速发展,性能强大的嵌入式AI开发板成为开发者和企业关注的焦点。NVIDIA近期推出的Jetson Orin Nano 8GB开发套件,凭借其40 TOPS算力、高效的Ampere架构GPU以及出色的边缘AI能力,引起了广泛关注。本文将从配置性…...
基于强化学习建立代理模型来预测飞机升阻力特性的一般步骤
以下是一个基于强化学习建立代理模型来预测飞机升阻力特性的一般步骤: 1. 问题定义与环境设置 明确目标:确定要准确预测飞机在不同飞行条件下的升力和阻力系数。状态空间定义:选取与飞机升阻力相关的状态变量,如飞行速度、攻角、…...
使用Qt创建悬浮窗口
在Qt中创建悬浮窗口(如无边框、可拖动的浮动面板或提示框)可以通过以下方法实现。以下是几种常见场景的解决方案: 方法1:使用无边框窗口 鼠标事件拖动 适用于自定义浮动工具窗口(如Photoshop的工具栏)。 …...
C/C++都有哪些开源的Web框架?
CppCMS CppCMS是一个采用C语言开发的高性能Web框架,通过模版元编程方式实现了在编译期检查RESTful路由系统,支持传统的MVC模式和多种语言混合开发模式。 CppCMS最厉害的功能是WebSocket,10万连接在内存中长期保存占用的大小不超过600MB&…...
Unity基于C#+UGUI解决方案,制作每日签到系统(本地存储签到数据)
一、需求介绍:基于本地存储系统制作一个每日签到系统界面,相关签到界面如下图所示,点击“签到有礼”按钮后就会跳转到“每日登录礼”这个界面,点击“立即签到”按钮之后,按钮就会置灰,而且按钮的文字会变成“等待明日”。 二、制作界面显示相关功能,需要在Unity中新建一…...
VBA+FreePic2Pdf 找出没有放入PDF组合的单个PDF工艺文件
设计部门针对某个项目做了一个工艺汇总报告,原先只要几十个工艺文件,组合成一个PDF,但后来要求要多放点PDF进去,但工艺文件都混在一起又不知道哪些是重复的,找上我让我帮忙处理一下,我开始建议让她重新再组…...
工程化与框架系列(31)--前端依赖管理实践
前端依赖管理实践 📦 引言 前端依赖管理是现代Web开发中的重要环节。本文将深入探讨前端依赖管理的最佳实践,包括包管理工具、版本控制、依赖分析和优化等方面,帮助开发者更好地管理项目依赖。 依赖管理概述 前端依赖管理主要包括以下方面…...
【vscode-01】vscode不同项目不同语言扩展插件隔离方案
vscode不同项目不同语言扩展插件隔离方案 1. 背景2. vscode 扩展插件隔离方案2.1 code-profile 配置文件2.2 配合extensions.json 1. 背景 最近打开vscode 发现越来越卡,这是一个轻量级代码编辑器,怎么会如此占用内存呢? 我使用了‘code --l…...
17 | 实现简洁架构的 Biz 层
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
DNS解析错误要怎么处理
在互联网时代,网络已经成为人们生活和工作中不可或缺的一部分。然而,当遇到DNS 解析错误时,原本畅通无阻的网络访问会突然陷入困境,让人感到十分困扰。DNS,即域名系统,它如同互联网的电话簿,将人…...
【Rust基础】Rust后端开发常用库
使用Rust有一段时间了,期间尝试过使用Rust做后端开发、命令行工具开发,以及做端侧模型部署,也尝试过交叉编译、FFI调用等,也算是基本入门了。在用Rust做后端接口开发时,常常会找不到一些合适库,而这些库在J…...
【附JS、Python、C++题解】Leetcode面试150题(9)——三数之和
一、题目 15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足: i!j、i!k 且 j! k ,同时还满足:nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意…...
脑电波控制设备:基于典型相关分析(CCA)的脑机接口频率精准解码方法
文章目录 前言一、CCA的用途二、频率求解思路三、输入数据结构四、判断方法五、matlab实践1.数据集获取及处理2.matlab代码3.运行及结果 六、参考文献 前言 在脑机接口(BCI)领域,有SSVEP方向,中文叫做稳态视觉诱发电位,当人观看闪烁的视觉刺激…...
Golang学习笔记_44——命令模式
Golang学习笔记_41——观察者模式 Golang学习笔记_42——迭代器模式 Golang学习笔记_43——责任链模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 事务管理系统2. 多媒体遥控器3. 操作审计系统 四、Go语言实现示例五、高级应用…...
vue项目如何实现条件查询?
目录 1.前端 2.后端 3.mybatis的sql语句 结语 1.前端 说白了就是,无论该参数是否是空字符串,都会传递到后端。(反正不是null就行)。 2.后端 在controller层中,使用RequestParam注解接收名为registerName的参数&…...