C#多线程之BackgroundWorker

2023-12-23 12:18

本文主要是介绍C#多线程之BackgroundWorker,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、BackgroundWorker介绍

我们有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应。解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作。新建线程可以用 Thread 类实现多线程同时操作。简单的方法可以通过 BackgroundWorker 类实现。BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。

  常用方法

  1.RunWorkerAsync 开始执行后台操作。引发 DoWork 事件

  2.CancelAsync 请求取消挂起的后台操作。

  注意:这个方法是将 CancellationPending 属性设置为 true,并不会终止后台操作。在后台操作中要检查

CancellationPending 属性,来决定是否要继续执行耗时的操作。

  3.ReportProgress引发 ProgressChanged 事件。

  常用属性

  1.CancellationPending 指示应用程序是否已请求取消后台操作。只读属性,默认为 false,当执行了 CancelAsync 方法后,值为 true。

  2.WorkerSupportsCancellation指示是否支持异步取消。要执行 CancelAsync 方法,需要先设置该属性为 true。

  3.WorkerReportsProgress指示是否能报告进度。要执行 ReportProgress 方法,需要先设置该属性为 true。

  常用事件

  1.DoWork 调用 RunWorkerAsync 方法时发生。

  2.RunWorkerCompleted后台操作已完成、被取消或引发异常时发生。

  3.ProgressChanged调用 ReportProgress 方法时发生。

二、实例

点击开始,出现动画,并计数。

xml

<Window x:Class="测试大数据的图表.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:测试大数据的图表"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid Name="grid1"><Button Content="开始" Height="23" HorizontalAlignment="Left" Margin="41,20,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /><Button Content="stop" Margin="165,18,543,377"  Click="Button_Click"/><DataGrid AutoGenerateColumns="False" Height="99" HorizontalAlignment="Left" Margin="40,70,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="441" /><Canvas Name="loading" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed" HorizontalAlignment="Center" VerticalAlignment="Center" Width="120" Height="120" Margin="187,76,241,85"><Ellipse Width="15" Height="15" Canvas.Left="55" Canvas.Top="31" Stretch="Fill" Fill="#FFD1D1F7" Opacity="1.0"/><Ellipse Width="15" Height="15" Canvas.Left="38" Canvas.Top="39" Stretch="Fill" Fill="Blue" Opacity="0.8"/><Ellipse Width="15" Height="15" Canvas.Left="36" Canvas.Top="58" Stretch="Fill" Fill="#FF0000FE" Opacity="0.7"/><Ellipse Width="15" Height="15" Canvas.Left="52" Canvas.Top="67" Stretch="Fill" Fill="Blue" Opacity="0.6"/><Ellipse Width="15" Height="15" Canvas.Left="68" Canvas.Top="61" Stretch="Fill" Fill="#FF2E2EFF" Opacity="0.5"/><Ellipse Width="15" Height="15" Canvas.Left="69" Canvas.Top="42" Stretch="Fill" Fill="#FF6F6FFF" Opacity="0.4"/><Canvas.RenderTransform><RotateTransform x:Name="SpinnerRotate" Angle="0" /></Canvas.RenderTransform><Canvas.Triggers><EventTrigger RoutedEvent="ContentControl.Loaded"><BeginStoryboard><Storyboard><DoubleAnimation Storyboard.TargetName="SpinnerRotate" Storyboard.TargetProperty="(RotateTransform.Angle)" From="0" To="360" Duration="0:0:0.8" RepeatBehavior="Forever" /></Storyboard></BeginStoryboard></EventTrigger></Canvas.Triggers></Canvas><Label Name="lab_pro" Content="Label" Height="28" Margin="140,14,315,239" /></Grid>
</Window>

C#

using System;
using System.ComponentModel;
using System.Windows;namespace 测试大数据的图表
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}BackgroundWorker bgMeet = new BackgroundWorker();private void button1_Click(object sender, RoutedEventArgs e){if (bgMeet.IsBusy) // 防止重复执行异步操作引发错误return;bgMeet.WorkerReportsProgress = true;//报告完成进度  bgMeet.WorkerSupportsCancellation = true;//允许用户终止后台线程 bgMeet.DoWork += new DoWorkEventHandler(bgMeet_DoWork);bgMeet.ProgressChanged += new ProgressChangedEventHandler(bgMeet_ProgressChanged);bgMeet.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgMeet_RunWorkerCompleted);bgMeet.RunWorkerAsync();}/// <summary>/// 异步操作完成或中途终止会触发该事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void bgMeet_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){loading.Visibility = System.Windows.Visibility.Collapsed;this.Dispatcher.Invoke(new Action(() =>{this.lab_pro.Content = "完成";}));}/// <summary>/// 提供一个在 0 到 100 之间的整数,它表示后台活动已完成的百分比/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void bgMeet_ProgressChanged(object sender, ProgressChangedEventArgs e){this.Dispatcher.Invoke(new Action(() =>{this.lab_pro.Content = e.ProgressPercentage;}));}/// <summary>/// 开始异步操作执行该方法/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void bgMeet_DoWork(object sender, DoWorkEventArgs e){this.Dispatcher.Invoke(new Action(() =>{loading.Visibility = System.Windows.Visibility.Visible;}));for (int i = 0; i < 505; i++){if (bgMeet.CancellationPending){e.Cancel = true;return;}bgMeet.ReportProgress(i);System.Threading.Thread.Sleep(100);}}private void Button_Click(object sender, RoutedEventArgs e){if (bgMeet != null && bgMeet.WorkerSupportsCancellation == true){loading.Visibility = System.Windows.Visibility.Hidden; ;bgMeet.CancelAsync();//取消后台操作  bgMeet.Dispose();//释放资源  }}}}

 

参考:

https://www.cnblogs.com/javier520/p/10842161.html

https://www.cnblogs.com/zhaoshujie/p/9634136.html

https://blog.csdn.net/qq_33222460/article/details/79946847

 

这篇关于C#多线程之BackgroundWorker的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/528008

相关文章

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

C# 委托中 Invoke/BeginInvoke/EndInvoke和DynamicInvoke 方法的区别和联系

《C#委托中Invoke/BeginInvoke/EndInvoke和DynamicInvoke方法的区别和联系》在C#中,委托(Delegate)提供了多种调用方式,包括Invoke、Begi... 目录前言一、 Invoke方法1. 定义2. 特点3. 示例代码二、 BeginInvoke 和 EndI

C#中的 Dictionary常用操作

《C#中的Dictionary常用操作》C#中的DictionaryTKey,TValue是用于存储键值对集合的泛型类,允许通过键快速检索值,并且具有唯一键、动态大小和无序集合的特性,常用操作包括添... 目录基本概念Dictionary的基本结构Dictionary的主要特性Dictionary的常用操作

C# winform操作CSV格式文件

《C#winform操作CSV格式文件》这篇文章主要为大家详细介绍了C#在winform中的表格操作CSV格式文件的相关实例,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录实例一实例效果实现代码效果展示实例二实例效果完整代码实例一实例效果当在winform界面中点击读取按钮时 将csv中

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

C# string转unicode字符的实现

《C#string转unicode字符的实现》本文主要介绍了C#string转unicode字符的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1. 获取字符串中每个字符的 Unicode 值示例代码:输出:2. 将 Unicode 值格式化

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr