BackgroundWorker类允许您在单独的线程上执行某个可能导致用户界面(UI)停止响应的耗时操作,下面来介绍一下这个线程类BackgroundWorker,大家可以结合这位大佬的这篇文章,说的比较仔细

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

1.属性

//bool类型,指示应用程序是否已请求取消后台操作。此属性通常放在用户执行的异步操作内部,用来判断用户是否取消执行异步操作。当执行BackgroundWorker.CancelAsync()方法时,该属性值将变为True。

public bool CancellationPending { get; }

//bool类型,指示BackgroundWorker是否正在执行一个异步操作。此属性通常放在BackgroundWorker.RunWorkerAsync()方法之前,避免多次调用RunWorkerAsync()方法引发异常。当执行BackgroundWorker.RunWorkerAsync()方法是,该属性值将变为True。
public bool IsBusy { get; }

//bool类型,指示BackgroundWorker是否可以报告进度更新。当该属性值为True是,将可以成功调用ReportProgress方法,默认为false

public bool WorkerReportsProgress { get; set; }

//bool类型,指示BackgroundWorker是否支持异步取消操作。当该属性值为True是,将可以成功调用CancelAsync方法取消工作线程。

public bool WorkerSupportsCancellation { get; set; }

2.方法

//取消线程操作,属性CancellationPending将变为True

public void CancelAsync ();

//执行该方法,将触发ProgressChanged事件

public void ReportProgress (int percentProgress);

//开始执行线程操作,触发DoWork事件,执行事件中的代码

public void RunWorkerAsync ();

3.事件

//当执行RunWorkerAsync方法的时候触发该事件

public event System.ComponentModel.DoWorkEventHandler DoWork;

//当执行ReportProgress方法的时候触发该事件

public event System.ComponentModel.ProgressChangedEventHandler ProgressChanged;

//当线程操作完成、或者被取消、或者抛出异常的时候触发该事件

public event System.ComponentModel.RunWorkerCompletedEventHandler RunWorkerCompleted;

4.接下来通过一个开始/结束/暂停/继续执行线程的例子来说明

namespace LoginUI
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class LoadingWindow : Window
{private BackgroundWorker _backgroundWorker;
        //初始化为终止状态(true),那么该方法将一直工作
private ManualResetEvent manualReset = new ManualResetEvent(true);public LoadingWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
#region
InitializeBackgroundWorker();
btnSatrt.Content = "开始";
btnStop.Content = "暂停";
btnEnd.Content = "结束";
#endregion
} //执行后台线程
private void btnSatrt_Click(object sender, RoutedEventArgs e)
{
//开始执行后台操作
_backgroundWorker.RunWorkerAsync();
btnSatrt.IsEnabled = false;
btnEnd.IsEnabled = true;
} //暂停/继续后台线程
private void btnStop_Click(object sender, RoutedEventArgs e)
{
if (btnStop.Content.ToString() == "暂停")
{
manualReset.Reset();//暂停当前线程的工作,发信号给waitOne方法,阻塞
btnStop.Content = "继续";
}
else
{
manualReset.Set();//继续当前线程的工作,发信号给waitOne方法,继续运行Waitone后面的代码
btnStop.Content = "暂停";
}
}
//结束后台线程
private void btnEnd_Click(object sender, RoutedEventArgs e)
{
_backgroundWorker.CancelAsync();
btnSatrt.IsEnabled = true;
btnEnd.IsEnabled = false;
}
    
private void InitializeBackgroundWorker()
{
#region
if (_backgroundWorker == null)
_backgroundWorker = new BackgroundWorker();
//bool类型,指示BackgroundWorker是否可以报告进度更新。当该属性值为True时,将可以成功调用ReportProgress方法
_backgroundWorker.WorkerReportsProgress = true;
//bool类型,指示BackgroundWorker是否支持异步取消操作。当该属性值为True是,将可以成功调用CancelAsync方法
_backgroundWorker.WorkerSupportsCancellation = true;
//执行RunWorkerAsync方法后触发DoWork,将异步执行backgroundWorker_DoWork方法中的代码
_backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
//执行ReportProgress方法后触发ProgressChanged,将执行ProgressChanged方法中的代码
_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);
//异步操作完成或取消时执行的操作,当调用DoWork事件执行完成时触发。
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
#endregion
} //backgroundWorker_DoWork完成后执行
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if((bool)e.Result==true)
{
progressBar.Value = 100;
lstbLog.Items.Add("操作已完成");
MessageBox.Show("操作已完成");
}
} private void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
            //ProgressPercentage是ReportProgress方法中第一个参数传递过来的
progressBar.Value = e.ProgressPercentage;
             //lstbLog是一个listView控件,UserState是ReportProgress方法中第二个参数传递过来的
lstbLog.Items.Add(e.UserState.ToString());
} //backgroundWorker_DoWork是运行在非UI线程上的,因此该内部代码应该避免与UI界面交互,交互的逻辑应该放到
//ProgressChanged和RunWorkerCompleted事件中
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i=0;i<=100;i++)
{
////如果ManualResetEvent的初始化为终止状态(true),那么该方法将一直工作,
//直到收到Reset信号,将阻塞。然后,直到收到Set信号,就继续工作。
manualReset.WaitOne();
//可以通过调用CancelAsync方法设置CancellationPending的值为false
if (_backgroundWorker.CancellationPending)
{
_backgroundWorker.ReportProgress(i, String.Format("{0}%,操作被用户申请结束", i));
_backgroundWorker.ReportProgress(0, String.Format("已完成{0}%",0 ));
e.Result = false;
break;
}
//调用 ReportProgress 方法,会触发ProgressChanged事件
_backgroundWorker.ReportProgress(i, String.Format("已完成{0}%", i));
System.Threading.Thread.Sleep(50);
if (i == 100)
{
//执行DoWork方法完成,设置为True
e.Result = true;
}
}
}


点击开始按钮,开始执行


点击结束,将会结束上述任务

点击暂停/继续按钮可以暂停/继续当前任务

上述每个按钮的功能逻辑还没有完善,但是基本的功能都实现了。本人也是个新手,如有什么问题麻烦指出,谢谢各位大佬!

WPF之BackgroundWorker的更多相关文章

  1. WPF 分页控件 WPF 多线程 BackgroundWorker

    WPF 分页控件 WPF 多线程 BackgroundWorker 大家好,好久没有发表一篇像样的博客了,最近的开发实在头疼,很多东西无从下口,需求没完没了,更要命的是公司的开发从来不走正规流程啊, ...

  2. WPF线程(Step2)——BackgroundWorker

    在WPF中第二个常用的线程处理方式就是BackgroundWorker. 以下是BackgroundWorker一个简单的例子. public partial class MainWindow : W ...

  3. 让你的WPF程序使用多线程——BackgroundWorker

    在wpf中可以使用许多方法执行异步操作.利用.NET的芳芳就是手动创建一个新的System.Threading.Thread对象,提供一步代码,并使用THread.Start()方法加载代码.这种方法 ...

  4. 【WPF/C#】使用BackgroundWorker实现多线程/异步操作

    做WPF时需要做一个异步加载时的Loading遮罩,搜Stackoverflow看到很多方法,看到了这个插件: BusyIndicator in the extended WPF Toolkit 同时 ...

  5. WPF 精修篇 BackgroundWorker

    原文:WPF 精修篇 BackgroundWorker 效果 <Grid> <Grid.RowDefinitions> <RowDefinition Height=&qu ...

  6. WPF 耗时操作时,加载loging 动画 (BackgroundWorker 使用方法)

    1.定义一个全局 BackgroundWorker private System.ComponentModel.BackgroundWorker bgMeet0; 2.设置执行耗时的任务为True b ...

  7. WPF 后台任务 等待动画 样例 && C# BackgroundWorker 详解

    运行效果: 前台代码: <Window x :Class="Waiting.Window1" xmlns="http://schemas.microsoft.com ...

  8. Wpf Backgroundworker

    <Window x:Class="WpfApp53.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20 ...

  9. WPF 线程 Dispatcher

    WPF 应用程序从两个线程开始: 一个用于处理呈现 一个用于管理 UI 呈现线程有效地隐藏在后台运行,而UI线程则接收输入.处理事件.绘制屏幕以及运行应用程序代码. 大多数应用程序都使用一个 UI 线 ...

随机推荐

  1. 关于使用docker volume挂载的注意事项

    Content 在用Docker进行持久化的存储的时候,有两种方式: 使用数据卷(volume) -v 容器绝对路径 或者 -v 已经创建的volume名称:容器绝对路径 2. 使用挂载点(共享宿主目 ...

  2. KingbaseES 多列分区的方法与性能

    前言 对于多列分区,可以选择单级多列的范围分区,也可以选择范围加子分区的方式.但二者在不同场景下对于性能是有差异的,这里的性能差异主要是分区裁剪引起的差异. 例子 创建两张分区表,采取不同的分区策略: ...

  3. Java 流处理之收集器

    Java 流(Stream)处理操作完成之后,我们可以收集这个流中的元素,使之汇聚成一个最终结果.这个结果可以是一个对象,也可以是一个集合,甚至可以是一个基本类型数据. 以记录 Record 为例: ...

  4. [LeetCode]-217.存在重复元素-简单

    217. 存在重复元素 给定一个整数数组,判断是否存在重复元素. 如果存在一值在数组中出现至少两次,函数返回 true .如果数组中每个元素都不相同,则返回 false . 示例 1: 输入: [1, ...

  5. Exchange 2019中的Unified Messaging(UM)

    前天,刚刚安装了测试用的Exchange 2019.安装过程和之前的2016一样,非常顺利.但是在用ECP管理服务器的时候遇到了一个报错.The term 'Get-UMService' is not ...

  6. Mybatis 一级缓存和二级缓存原理区别 (图文详解)

    Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别@mikechen Mybatis缓存 缓存就是内存中的数据,常常来自对数据库查询结 ...

  7. 一门能让你五分钟学会的语言-Brainfuck

    看到标题,不出意外的话,你肯定开始骂我了:**标题党,什么编程语言五分钟就能学会? 其实我本来也是不相信的,但是学过了才知道这是真的. 1.Brainfuck 看到这个小标题,不要误会,我没有骂人. ...

  8. Elasticsearch:Elasticsearch SQL介绍及实例 (一)

    转载自:https://blog.csdn.net/UbuntuTouch/article/details/105658911

  9. 解决centos系统突然间网络不通的问题:Global IPv6 forwarding is disabled in configuration, but not currently disabled in kernel

    问题描述:公司里的一台centos 7.6主机,连接公司的路由器,里面设置的静态ip,之前用的好好的,但是有一次突然间ping不通了,之前是可以ping通的. 问题分析: 查看网络配置文件: TYPE ...

  10. 初试Jenkins2.0 Pipeline持续集成

    转载自:https://cloud.tencent.com/developer/article/1010628 1.Jenkins 2.0介绍 先介绍下什么是Jenkins 2.0,Jenkins 2 ...