前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2023年12月 Winform控件专题 BackgroundWorker控件详解

【愚公系列】2023年12月 Winform控件专题 BackgroundWorker控件详解

原创
作者头像
愚公搬代码
修改2023-12-28 08:11:30
2760
修改2023-12-28 08:11:30
举报
文章被收录于专栏:历史专栏历史专栏

🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。

🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。

🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

Winform控件是Windows Forms中的用户界面元素,它们可以用于创建Windows应用程序的各种视觉和交互组件,例如按钮、标签、文本框、下拉列表框、复选框、单选框、进度条等。开发人员可以使用Winform控件来构建用户界面并响应用户的操作行为,从而创建功能强大的桌面应用程序。

🚀一、BackgroundWorker控件详解

BackgroundWorker控件是Windows Forms中提供的一个轻量级组件,用于在后台线程中执行耗时的操作,避免阻塞UI线程,提高应用程序的响应性能。BackgroundWorker控件通过在异步线程中执行操作,并在操作完成后在UI线程上引发事件来完成此目的。

BackgroundWorker控件提供了以下事件和方法,以方便在异步操作中实现进度报告、取消操作、完成操作等功能:

事件:

  • DoWork:异步线程执行操作的事件。
  • ProgressChanged:异步线程报告操作进度的事件。
  • RunWorkerCompleted:异步操作完成时引发的事件。

方法:

  • RunWorkerAsync:启动异步操作的方法。
  • CancelAsync:请求取消异步操作的方法。

使用BackgroundWorker控件时,需要注意以下几点:

  • 在DoWork事件中执行耗时的操作,不能调用UI线程上的控件,如需更新UI上的控件,需要在ProgressChanged事件中调用。
  • 在RunWorkerCompleted事件中发生的任何异常都会被视为未处理异常,并导致应用程序崩溃。
  • 如果需要在DoWork事件中定期检查是否已请求取消异步操作,可以使用CancellationPending属性,该属性为只读属性,如果已请求取消操作,则为true,否则为false。

🔎1.属性介绍

🦋1.1 WorkerReportsProgress

BackgroundWorker控件的WorkerReportsProgress属性用于指示是否支持异步报告进度。如果将其设置为true,则可以在异步操作中使用ReportProgress方法报告进度。如果设置为false,则不能使用ReportProgress方法,否则会引发InvalidOperationException异常。

WorkerReportsProgress属性的默认值为false。如果需要在异步操作中报告进度,则必须将其设置为true。

下面是一个示例,演示如何设置WorkerReportsProgress属性并在异步操作中报告进度:

代码语言:csharp
复制
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // 设置WorkerReportsProgress属性为true
    backgroundWorker1.WorkerReportsProgress = true;

    // 执行耗时的操作
    for (int i = 0; i <= 100; i++)
    {
        Thread.Sleep(50);
        // 报告进度
        backgroundWorker1.ReportProgress(i);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // 更新UI上的控件
    progressBar1.Value = e.ProgressPercentage;
}

private void button1_Click(object sender, EventArgs e)
{
    // 启动异步操作
    backgroundWorker1.RunWorkerAsync();
}

在上述示例中,需要在DoWork事件中将WorkerReportsProgress属性设置为true,以启用ReportProgress方法,然后在循环中调用ReportProgress方法报告进度。在ProgressChanged事件中更新UI上的进度条控件。

🦋1.2 WorkerSupportsCancellation

BackgroundWorker控件是一个可用于执行后台操作的组件。它提供了一个异步操作模型,可以允许后台线程执行操作,并在操作完成后通知前台线程。

WorkerSupportsCancellation属性是BackgroundWorker控件的一个属性,用于指示后台操作是否支持取消。当WorkerSupportsCancellation属性设置为true时,可以通过调用BackgroundWorker控件的CancelAsync方法来请求取消后台操作。

下面是一个简单的示例,演示如何在Winform中使用BackgroundWorker控件和WorkerSupportsCancellation属性:

代码语言:csharp
复制
private BackgroundWorker backgroundWorker1;

private void buttonStart_Click(object sender, EventArgs e)
{
    // 初始化BackgroundWorker控件
    backgroundWorker1.WorkerSupportsCancellation = true;
    // 启动异步操作
    backgroundWorker1.RunWorkerAsync();
}

private void buttonCancel_Click(object sender, EventArgs e)
{
    // 请求取消异步操作
    backgroundWorker1.CancelAsync();
}

// 后台操作方法
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    backgroundWorker1.WorkerReportsProgress = true;

    for (int i = 1; i <= 100; i++)
    {
        // 检查是否请求取消
        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
            break;
        }

        // 模拟长时间操作
        Thread.Sleep(100);

        // 更新进度条
        backgroundWorker1.ReportProgress(i);
    }
}

// 异步操作完成方法
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
        MessageBox.Show("异步操作已取消!");
    else if (e.Error != null)
        MessageBox.Show("异步操作发生错误:" + e.Error.Message);
    else
        MessageBox.Show("异步操作已完成!");
}

在这个示例中,当点击“开始”按钮时,创建并启动BackgroundWorker控件,并在其中执行一个模拟的长时间操作。在操作执行过程中,每次更新进度条并检查是否请求取消。当点击“取消”按钮时,调用BackgroundWorker控件的CancelAsync方法来请求取消操作。当异步操作完成时,根据操作是否被取消或是否发生错误来显示相应的提示信息。

通过使用BackgroundWorker控件和WorkerSupportsCancellation属性,可以轻松实现异步操作的取消功能,提高应用程序的用户体验。

🔎2.常用场景

BackgroundWorker控件在Winform应用程序中的常用场景有:

  1. 长时间运行的任务:当需要执行耗时的操作时,比如读取大量数据、计算复杂算法、网络请求等,BackgroundWorker可以在后台执行,避免阻塞UI线程,提高用户体验。
  2. 操作进度条:在执行长时间运行的任务时,可以使用BackgroundWorker来更新进度条,让用户知道任务的进度和剩余时间。
  3. 异步处理问题:在Winform应用程序中,有时需要异步地执行某些操作,比如在窗口关闭时保存数据、进行数据同步等,BackgroundWorker可以帮助实现异步操作,避免阻塞UI线程。
  4. 实时更新UI:有些操作需要实时更新UI,比如显示传感器数据、播放音频等,BackgroundWorker可以在后台执行数据处理和更新UI,避免UI线程被阻塞。

🔎3.具体案例

以下是一个利用 BackgroundWorker 控件实现在后台线程中计算斐波那契数列,并将结果显示在 UI 上。

首先,在 UI 界面中添加一个 Label 控件用于显示结果,一个 Button 控件作为触发事件的按钮,以及一个 BackgroundWorker 控件。

在代码中,先引入 System.ComponentModel 命名空间,这个命名空间包含了 BackgroundWorker 类。

代码语言:csharp
复制
using System.ComponentModel;

在类中定义全局变量和 BackgroundWorker 对象:

代码语言:csharp
复制
public partial class Form1 : Form
{
    private int n = 10; // 计算斐波那契数列的项数
    private long[] fib; // 保存斐波那契数列的数组
    private BackgroundWorker bgWorker; // BackgroundWorker 对象

    public Form1()
    {
        InitializeComponent();

        // 创建 BackgroundWorker 对象
        bgWorker = new BackgroundWorker();

        // 设置 WorkerReportsProgress 和 WorkerSupportsCancellation 属性
        bgWorker.WorkerReportsProgress = true;
        bgWorker.WorkerSupportsCancellation = true;

        // 注册事件处理程序
        bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
        bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
        bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
    }

    // ...
}

接下来,定义 BackgroundWorker 的三个事件处理程序,分别是 DoWork、ProgressChanged 和 RunWorkerCompleted。这些事件将在后台线程中执行,并用于计算斐波那契数列、更新进度和显示结果。

代码语言:csharp
复制
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // 计算斐波那契数列
    fib = new long[n];
    fib[0] = 0;
    fib[1] = 1;

    for (int i = 2; i < n; i++)
    {
        if (bgWorker.CancellationPending)
        {
            e.Cancel = true;
            return;
        }

        fib[i] = fib[i - 2] + fib[i - 1];
        int progress = (int)(((double)i / n) * 100);
        bgWorker.ReportProgress(progress);
        Thread.Sleep(100); // 模拟耗时操作
    }
}

private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // 显示进度条
    progressBar1.Value = e.ProgressPercentage;
}

private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // 显示结果
    if (e.Cancelled)
    {
        label1.Text = "计算取消";
    }
    else if (e.Error != null)
    {
        label1.Text = "计算错误";
    }
    else
    {
        label1.Text = "结果:\n" + string.Join(", ", fib);
    }

    // 恢复按钮状态
    button1.Enabled = true;
}

在按钮的 Click 事件处理程序中,开启 BackgroundWorker 的线程,并禁用按钮以防止用户重复点击。

代码语言:csharp
复制
private void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false; // 禁用按钮

    // 开启线程
    if (!bgWorker.IsBusy)
    {
        bgWorker.RunWorkerAsync();
    }
}

最后,添加一个取消计算的按钮,并在其 Click 事件处理程序中调用 CancelAsync() 方法取消后台线程的计算。

代码语言:csharp
复制
private void button2_Click(object sender, EventArgs e)
{
    if (bgWorker.IsBusy)
    {
        bgWorker.CancelAsync();
    }
}

完整代码:

代码语言:csharp
复制
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace BackgroundWorkerExample
{
    public partial class Form1 : Form
    {
        private int n = 10; // 计算斐波那契数列的项数
        private long[] fib; // 保存斐波那契数列的数组
        private BackgroundWorker bgWorker; // BackgroundWorker 对象

        public Form1()
        {
            InitializeComponent();

            // 创建 BackgroundWorker 对象
            bgWorker = new BackgroundWorker();

            // 设置 WorkerReportsProgress 和 WorkerSupportsCancellation 属性
            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;

            // 注册事件处理程序
            bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
            bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
            bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false; // 禁用按钮

            // 开启线程
            if (!bgWorker.IsBusy)
            {
                bgWorker.RunWorkerAsync();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (bgWorker.IsBusy)
            {
                bgWorker.CancelAsync();
            }
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // 计算斐波那契数列
            fib = new long[n];
            fib[0] = 0;
            fib[1] = 1;

            for (int i = 2; i < n; i++)
            {
                if (bgWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                fib[i] = fib[i - 2] + fib[i - 1];
                int progress = (int)(((double)i / n) * 100);
                bgWorker.ReportProgress(progress);
                Thread.Sleep(100); // 模拟耗时操作
            }
        }

        private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // 显示进度条
            progressBar1.Value = e.ProgressPercentage;
        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // 显示结果
            if (e.Cancelled)
            {
                label1.Text = "计算取消";
            }
            else if (e.Error != null)
            {
                label1.Text = "计算错误";
            }
            else
            {
                label1.Text = "结果:\n" + string.Join(", ", fib);
            }

            // 恢复按钮状态
            button1.Enabled = true;
        }
    }
}

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🚀前言
  • 🚀一、BackgroundWorker控件详解
    • 🔎1.属性介绍
      • 🦋1.1 WorkerReportsProgress
      • 🦋1.2 WorkerSupportsCancellation
    • 🔎2.常用场景
      • 🔎3.具体案例
      相关产品与服务
      云开发 CloudBase
      云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档