BackgroudWork的详细用法,实例


一、什么是BackgroudWorker?


    1、简言
        backgroudworkd就是一个异步单线程,专门为入门级人员开发的。还可以显示进度条。操作简单实用,属于老技术。
        注意:如果调用两次这个线程,将会出错。
        
    
    2、backgroudworker介绍
        BackgroundWorker 是一个在 .NET Framework 中提供的用于简化多线程编程的辅助类。它允许在后台线程中执行耗时的操作,同时在主线程中更新用户界面。BackgroundWorker 提供了一种简单的方法来处理异步操作,避免阻塞主线程,以提高用户界面的响应性。

        使用 BackgroundWorker 的一般步骤(下面是动态生成该控件,拖放控件只看3-5步):

        (1)实例化一个 BackgroundWorker 对象。
        (2)注册事件处理程序,如 DoWork(处理耗时操作)、ProgressChanged(报告进度更新)和 RunWorkerCompleted(在操作完成后进行清理等处理)。
        (3)在 DoWork 事件处理程序中执行需要在后台线程中完成的操作。可以使用 ReportProgress 方法报告进度。
        (4)在 ProgressChanged 事件处理程序中更新界面,以反映进度的变化。
        (5)在 RunWorkerCompleted 事件处理程序中进行清理操作并处理操作的结果。

        通过 BackgroundWorker,你可以简化异步编程,使得处理耗时操作和更新用户界面变得更加方便。然而,需要注意的是,BackgroundWorker 是一个较为旧的技术,在更高级的异步编程场景中,可能需要使用 Task、async/await 等更为现代的机制和模式。
            
    3、动态生成的控件与编写前拖放的控件,两者在资源耗费上哪个更节约?
        动态生成的控件与编写前拖放的控件,两者在资源耗费上没有明确的答案,取决于具体的实现方式和使用场景。
        动态生成的控件通常是在运行时根据需求动态创建的,这样可以根据实际需要灵活地生成控件,避免了不必要的资源浪费。然而,动态生成控件需要在运行时进行额外的计算和内存分配,可能会增加一定的开销。
        编写前拖放的控件通常是在设计时通过可视化编辑器进行的,可以直接在界面上进行拖放和布局,相对来说更加直观和方便。但是,编写前拖放的控件可能会在设计时就占用一定的资源,尤其是对于复杂的界面和大量的控件。
        因此,要选择哪种方式需要根据具体的需求和场景来决定。如果界面较为简单,控件数量有限,且需要频繁动态改变控件的情况下,动态生成的控件可能更加节约资源。如果界面复杂,控件数量较多且固定,且不需要频繁改变控件的情况下,编写前拖放的控件可能更加方便和节约资源。

    4、一个 BackgroundWorker 只能同时启动一次 RunAsync?
        是的,一个 BackgroundWorker 只能同时启动一次 RunAsync。 BackgroundWorker 是用于在后台线程执行长时间运行的任务的组件,它提供了一种简单的方式来执行异步操作并在完成后返回结果。
        当调用 BackgroundWorker 的 RunAsync 方法时,它会在后台线程中执行指定的操作。在操作完成之前,不能再次调用 RunAsync 方法。如果尝试再次调用 RunAsync 方法,会抛出 InvalidOperationException 异常。
        如果需要同时执行多个异步操作,可以考虑使用 Task 类或其他多线程机制来实现。 Task 类提供了更灵活和强大的异步编程模型,可以同时启动多个任务并进行管理。
    
    5、BackgroundWorker的各事件在什么线程中执行?
        DoWork 事件处理程序是在后台线程中执行的,用于处理耗时的操作。这使得主线程可以保持响应,并且不会被阻塞。
        
        BackgroundWorker 类中的ProgressChanged 和 RunWorkerCompleted由主线程发起和处理的。
        
        ProgressChanged 事件用于报告进度的更新,
        RunWorkerCompleted 事件在后台操作完成后触发,
        ReportProgress 方法用于在 DoWork 中报告进度
        CancelAsync 方法用于请求取消操作。
        
        eportProgress 方法是在 DoWork 方法中由后台线程发起的。它用于向主线程报告进度信息。

    6、前台线程,后台线程,主线程,子线程,同步线程,异步线程
        前台线程是指会阻塞应用程序关闭的线程,它会等待所有前台线程执行完毕后才会终止应用程序。在C#中,Thread 类创建的线程默认是前台线程。
        后台线程是一种在后台执行的线程,它与主线程(前台线程)相对。后台线程不会阻止应用程序的退出,当所有的前台线程结束时,后台线程会自动终止。后台线程通常用于执行一些不需要与用户界面交互的任务,例如执行耗时的计算、文件操作、网络请求等。它们可以在应用程序的后台默默地执行,而不会阻塞用户界面的响应。
        主线程一般指调用线程,即运行最开始的线程,比如form1的UI线程,或控制台的Main(),子线程是相对于主线程而说,由主线程启动的另一个线程一般叫子线程(父生子)。
        
        异步线程和同步线程的区别在于线程之间的关系和执行方式。异步线程是独立运行的,彼此并行执行,而同步线程需要与其他线程协作,相互等待或同步执行。
        异步线程是指在应用程序中同时执行的线程,它们可以与当前线程并行执行,彼此独立运行,并且它们的执行顺序和完成时间不受当前线程的干预。异步线程通常用于执行耗时的操作,以避免阻塞当前线程。

        同步线程是指按照一定的顺序执行的线程,它们需要与当前线程协作,相互等待或同步执行。同步线程通常用于保证线程安全性或确保任务的有序执行。

        异步和同步的区别在于线程之间的关系和执行方式:

        异步线程是独立运行的,彼此之间没有干预,它们可以并行执行,不需要等待其他线程的完成。
        同步线程需要与其他线程协作,它们可能会相互等待或同步执行,以确保任务的有序执行或线程安全性。
        异步线程通常用于执行耗时的操作,以避免阻塞当前线程,提高应用程序的响应性。
        同步线程通常用于保证线程安全性,确保多个线程对共享资源的访问不会发生冲突。

        Thread 可以用于创建前台线程或后台线程,它的行为取决于线程的创建方式和所在的上下文。在 Task 中使用的 Thread 是后台线程,它是异步执行的,不会阻塞主线程。而在 UI 主线程中使用的 Thread 是前台线程,如果阻塞主线程,会导致界面卡顿或无响应。
        
        在 Task 中使用的 Thread 是一个后台线程,它是异步执行的。在这种情况下,Task 会创建一个新的线程来执行异步操作,而主线程可以继续执行其他任务。这个后台线程与主线程是独立的,它不会阻塞主线程的执行。

        而在 UI 主线程中使用的 Thread 是一个前台线程,它会阻塞主线程的执行。在 UI 应用程序中,主线程通常是用于处理用户界面的线程,如果在主线程中执行耗时操作,会导致界面卡顿或无响应。因此,为了保持用户界面的流畅性,通常会将耗时操作放在后台线程中执行。

        注意,如果在 UI 主线程中使用 Thread.Join() 方法等待同步线程的执行,那么主线程会被阻塞,直到同步线程执行完毕。这种情况下,同步线程会阻塞当前线程,使得当前线程成为同步线程。
        
        BackgroundWorker 中的子线程就是后台线程。后台线程是一种在应用程序运行期间在后台执行的线程,与主线程并行执行,不会阻塞主线程的执行。
        BackgroundWorker 创建的子线程默认是后台线程,它在后台执行长时间运行的操作,而不会阻塞主线程。这使得主线程可以继续响应用户界面的交互,而不会出现假死的情况。
        总结,后台线程是一种异步线程的实现方式,它可以在后台执行长时间运行的操作,而不会阻塞主线程的执行。异步线程可以是后台线程或前台线程,而后台线程是一种特定的异步线程类型。
        
    7、为什么常说异步操作,而不说异步线程?
        为了使编程更简单,刻意避免使用底层线程池或异步线程的概念,而使用更高级抽象封装的概念,故说异步操作,不说异步线程。
        Task 是对异步操作的高级封装,它提供了一种更高级的编程模型,使得异步编程变得更加简单和易于理解。通过使用 Task,我们可以将异步操作的执行过程和结果进行抽象和封装,而不需要直接操作线程。

        Task 的设计目的是为了让开发者能够更方便地编写异步代码,而不需要过多地关注底层线程的细节。它提供了一系列的方法和属性,用于管理异步操作的状态、处理异常、获取结果等。开发者可以通过使用这些方法和属性,来编写和管理异步操作的执行逻辑。

        通过使用 Task,开发者可以将复杂的异步操作分解为多个小任务,并通过任务之间的依赖关系来组织和管理这些任务。这样可以使得异步编程更加直观和易于理解,避免了直接操作线程所带来的复杂性和困扰。

        因此,使用 Task 可以让开发者更轻松地入门和使用异步编程,而不需要深入了解底层线程的细节和复杂性。它提供了一种更高级的抽象和概念,使得异步编程变得更加易于理解和使用。

二、BackgoundWorker实例


    1、一个backgroudnworker控件,button,textbox,label。界面如下
        

        
        程序:

        private void BtnRun_Click(object sender, EventArgs e){backgroundWorker1.WorkerReportsProgress = true;//要显示进度label1.BackColor = Color.Transparent;label1.Text = "0";backgroundWorker1.RunWorkerAsync();// backgroundWorker1.RunWorkerAsync("Hello world");//a}private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)//子线程{//string s = e.Argument as string;//bfor (int i = 0; i < 101; i++){Thread.Sleep(100);backgroundWorker1.ReportProgress(i);//cShowMsg(i.ToString());//ShowMsg(i.ToString()+s );//d}e.Result = "线程中的信息";//e}private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)//主线程{progressBar1.Value = e.ProgressPercentage;//flabel1.Text = e.ProgressPercentage.ToString();}private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)//主线程{ShowMsg("程序执行完成。");ShowMsg(e.Result.ToString());//g}private void ShowMsg(string s){if (TxtInfo.InvokeRequired){ BeginInvoke(new Action(() => { TxtInfo.AppendText($"{s} \r\n"); })); }else{ TxtInfo.AppendText($"{s} \r\n"); }}


        
    2、RunWorkerAsync()是启动子线程,可以带参数见a处
        参数在子线程通过DoWorkEventArgs e传递过来,用e.Argument来转换,在b处进行变换,包括以数组形式的方式传递参数。
        在d处接收数据,或处理数据。
    
    3、c处报告进度。
        ReportProgress 方法的 progressPercentage 参数应该是一个介于 0 到 100 之间的整数值,用于表示进度的百分比。例如,通过调用 backgroundWorker1.ReportProgress(50),您可以向 ProgressChanged 事件处理程序报告任务完成了一半。
        从 DoWork 事件处理程序中调用 ReportProgress 方法可以将更新的进度信息传递给 ProgressChanged 事件处理程序。然后,您可以在 ProgressChanged 事件处理程序中更新进度条或执行其他操作以反映操作的进度。
        在c处传出数据,在ProgressChanged事件的ProgressChangedEventArgs e中接收,通过在f处的e.ProgressPercentage提取数据(object)。
        
    4、e处的Result属性是一个暂存仓库,相当于一个公有变量,把子线程中的值传递到主线程,比如g处,也可以在ProgressChanged事件中传递。
        
        
    5、简言之:如果没有必要,尽量不用backgroundworker这个老办法。
 

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

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

相关文章

025: vue父子组件中传递方法控制:$emit,$refs,$parent,$children

第025个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

Redis 复制(replica)

1. 是什么 1.1 官网地址 https://redis.io/docs/management/replication/ 1.2 一句话 1. 就是主从复制&#xff0c;master以写为主&#xff0c;slave以读为主 2. 当master数据变化的时候&#xff0c;自动将新的数据异步同步到其它slave数据库 2. 能干嘛 1. 读写分离 2. 容灾…

正规黄金代理的三大要素

对于现货黄金投资来说&#xff0c;寻找一个正规的黄金代理是十分重要的问题。在目前的现货黄金投资市场中&#xff0c;现货黄金代理的数量很多&#xff0c;他们都致力于耕耘现货黄金投资市场。当越来越多的专业人士加入到现货黄金投资的市场中当中时&#xff0c;这个市场将会越…

手写Mybatis:第10章-使用策略模式,调用参数处理器

文章目录 一、目标&#xff1a;参数处理器二、设计&#xff1a;参数处理器三、实现&#xff1a;参数处理器3.1 工程结构3.2 参数处理器关系图3.3 入参数校准3.4 参数策略处理器3.4.1 JDBC枚举类型修改3.4.2 类型处理器接口3.4.3 模板模式&#xff1a;类型处理器抽象基类3.4.4 类…

Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录

Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录 目录 Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录 一、简单介绍 二、OKHttp 4.xx 的 SDK 封装 aar 给 Unity 的使用注意 三、附录 OKHttp 的…

德庄借助纷享销客CRM系统实现高效管理

德庄集团创于1999年&#xff0c;是一家集餐饮产业、食品产业、科技研发及文化研究为一体的现代化民营企业&#xff0c;下属9家子公司、2大现代化食品加工基地、1所研究所、1所培训学校、1个技术中心。拥有德庄、青一色、滟设、香漫谷、饭空等8大子品牌&#xff0c;呈现出良好的…

IDEA新建SpringBoot项目时启动编译报错:Error:java: 无效的源发行版: 17

文章目录 原因检查解决步骤修改jdk修改SpringBoot版本 原因 出现这种错误的原因可能是&#xff1a; 本机默认使用&#xff08;编译&#xff09;的jdk与该项目所使用的jdk版本不同。 jdk版本不适用于这个Idea&#xff0c;很典型的一个例子就是使用的Idea是2020的&#xff0c;而…

【前端】CSS-Flex弹性盒模型布局

目录 一、前言二、Flex布局是什么1、任何一个容器都可以指定为Flex布局2、行内元素也可以使用Flex布局3、Webkit内核的浏览器&#xff0c;必须加上-webkit前缀 三、基本概念四、flex常用的两种属性1、容器属性2、项目属性 五、容器属性1、flex-direction①、定义②、语句1&…

模糊测试面面观 | 模糊测试是如何发现异常情况的?

协议模糊测试是一种用于评估通信协议、文件格式和API实现系统安全性和稳定性的关键技术。在模糊测试过程中&#xff0c;监视器扮演着关键角色&#xff0c;它们能够捕获异常情况、错误响应、资源利用等&#xff0c;为测试人员提供有价值的信息&#xff0c;有助于发现潜在漏洞和问…

汽车3D HMI图形引擎选型指南【2023】

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 2002年&#xff0c;电影《少数派报告》让观众深入了解未来。 除了情节的核心道德困境之外&#xff0c;大多数人都对它的技术着迷。 我们看到了自动驾驶汽车、个性化广告和用户可以无缝交互的 3D 计算机界面。 令人惊讶的是…

数字人创作+SadTalker+GTX1080

https://github.com/OpenTalker/SadTalker 开源项目 SadTalker模型是一个使用图片与音频文件自动合成人物说话动画的开源模型&#xff0c;我们自己给模型一张图片以及一段音频文件&#xff0c;模型会根据音频文件把传递的图片进行人脸的相应动作&#xff0c;比如张嘴&#xf…

02-系统篇-内存分布

一.进程中的内存分布 进程是应用程序运行的单位&#xff0c;进程在内存中运行时&#xff0c;各个部分分布的情况如图。 1.栈内存(statck) 特点:后进先出 系统一般会对栈的大小进行限制&#xff0c;可以用命令进行查看&#xff0c;如下&#xff0c;700是进程号&#xff0c;栈被…

Python学习 -- Math模块和Random模块

math 模块提供了许多数学函数&#xff0c;用于执行各种数学运算。以下是一些常用的 math 函数以及相应的示例代码&#xff1a; math.sqrt(x): 计算平方根。 import math x 25 square_root math.sqrt(x) print(f"√{x} {square_root}") math.pow(x, y): 计算 x …

机器学习(吴恩达第一课)

课程链接 文章目录 第一周1、机器学习定义2、监督学习(Supervised learning)1、回归(Regression)2、分类(Classification) 3、无监督学习(Unsupervised learning)4、线性回归模型5、代价函数6、梯度下降(Gradient descent)1、学习率2、用于线性回归的梯度下降 第二周(多维特征…

W5500-EVB-PICO进行MQTT连接订阅发布教程(十二)

前言 上一章我们用开发板通过SNTP协议获取网络协议&#xff0c;本章我们介绍一下开发板通过配置MQTT连接到服务器上&#xff0c;并且订阅和发布消息。 什么是MQTT&#xff1f; MQTT是一种轻量级的消息传输协议&#xff0c;旨在物联网&#xff08;IoT&#xff09;应用中实现设备…

MATLAB中mod函数转化为C语言

背景 有项目算法使用matlab中mod函数进行运算&#xff0c;这里需要将转化为C语言&#xff0c;从而模拟算法运行&#xff0c;将算法移植到qt。 MATLAB中mod简单介绍 语法 b mod(a,m) 说明 b mod(a,m) 返回 a 除以 m 后的余数&#xff0c;其中 a 是被除数&#xff0c;m 是…

数字孪生与GIS:智慧城市的未来之路

数字孪生和地理信息系统&#xff08;GIS&#xff09;是两个在现代科技中崭露头角的概念&#xff0c;它们的融合为智慧城市项目带来了革命性的机会。本文将解释数字孪生为何需要融合GIS&#xff0c;并以智慧城市项目为例进行说明。 数字孪生是一种虚拟模型&#xff0c;它精确地…

行军遇到各种复杂地形怎么处理?

行军遇到各种复杂地形怎么处理&#xff1f; 【安志强趣讲《孙子兵法》第30讲】 【原文】 凡军好高而恶下&#xff0c;贵阳而贱阴&#xff0c;养生而处实&#xff0c;军无百疾&#xff0c;是谓必胜。 【注释】 阳&#xff0c;太阳能照到的地方。阴&#xff0c;太阳照不到的地方。…

【Python】从入门到上头— IO编程(8)

文章目录 一.IO编程是什么二.文件读写1.读取文件2.file-like Object二进制文件字符编码 3.写文件file对象的常用函数常见标识符 三.StringIO和BytesIO1.StringIO2.BytesIO 四.操作文件和目录五.序列化和反序列化1.pickle.dumps()2.pickle.loads()3.JSON 一.IO编程是什么 IO在计…

vue3 搭配ElementPlus做基础表单校验 自定义表单校验

<script setup> import { ref, reactive } from vue// 表单元素 const dom ref(null) // 校验规则 const rules {name: [{ required: true, message: 请输入活动名称, trigger: blur }],//校验手机号格式phone: [{ required: true, message: "请输入电话", t…