C# BackgroundWorker用法详解

我们来详细讲解一下C#中的BackgroundWorker用法。

一、BackgroundWorker 是什么?

在C#中,BackgroundWorker是一个多线程组件,用于在后台执行一个操作并在主界面上更新相应的进度。它避免了在主线程中直接执行操作而引起的冻结UI界面的问题。

二、BackgroundWorker 的声明

我们使用 BackgroundWorker,需要在代码中添加一个 BackgroundWorker 控件。在 Visual Studio 中,您可以使用工具箱中的控件添加 BackgroundWorker,也可以使用设计器将其添加到表单中。

using System.ComponentModel;

namespace MyApplication
{
    public class MyClass
    {
        BackgroundWorker backgroundWorker;

        public MyClass()
        {
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
            backgroundWorker.WorkerReportsProgress = true;  
        }
    }
}

这个代码片段中,我们首先在类中声明了 BackgroundWorker 对象。我们还初始化了 backgroundWorker 对象并指定了三个事件处理程序。

  • DoWork: 当调用 RunWorkerAsync 方法时,这个事件处理程序将异步执行。
  • RunWorkerCompleted: 这个事件处理程序在异步操作完成并结束时调用。
  • ProgressChanged: 这个事件处理程序在异步操作执行并更改了进度报告时调用。

您还可以在构造函数中设置 WorkReportsProgress 属性为 true,以便在异步操作执行时能够报告进度。

三、BackgroundWorker 的常用方法和属性

BackgroundWorker 有以下常用方法和属性:

  • DoWorkEventArgs.Argument 属性:获取指定异步任务的参数。通过这个属性,我们可以向异步任务传递参数。
  • BackgroundWorker.RunWorkerAsync 方法:启动异步操作。
  • BackgroundWorker.CancellationPending 属性:获取异步操作是否应被取消的值。
  • BackgroundWorker.CancelAsync 方法:请求取消异步操作。
  • BackgroundWorker.ReportProgress 方法:报告异步操作的进度。

四、BackgroundWorker 的使用示例

示例1:异步操作,可取消

假设我们要执行一个耗时的操作,这里使用一个简单的循环。因为循环执行时间较长,我们需要在一个单独的线程中执行,以确保应用程序在执行操作时不会被冻结。

这里我们以一个计数器为例,每100ms加1,达到10时程序结束。

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    int total = (int)e.Argument;
    int count = 0;
    while (count < total)
    {
        if (worker.CancellationPending)
        {
            e.Cancel = true;
            break;
        }
        Thread.Sleep(100);
        count++;
        int progress = (int)((double)count / total * 100);
        worker.ReportProgress(progress, count);
    }
}

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("操作被取消");
    }
    else if (e.Error != null)
    {
        MessageBox.Show("操作出现错误: " + e.Error.Message);
    }
    else
    {
        MessageBox.Show("操作完成");
    }
}

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
    label.Text = "计数:" + e.UserState.ToString();
}

private void btnStart_Click(object sender, EventArgs e)
{
    int count = 10;
    if (int.TryParse(textBox.Text, out count))
    {
        if (!backgroundWorker.IsBusy)
        {
            btnStart.Enabled = false;
            btnCancel.Enabled = true;
            progressBar.Value = 0;
            label.Text = "计数:0";
            backgroundWorker.RunWorkerAsync(count);
        }
    }
    else
    {
        MessageBox.Show("请输入一个数字");
    }
}

private void btnCancel_Click(object sender, EventArgs e)
{
    if (backgroundWorker.IsBusy)
    {
        btnCancel.Enabled = false;
        backgroundWorker.CancelAsync();
    }
}

在这个示例中,我们使用 DoWork 事件完成循环操作。当 BackgroundWorker 的 CancellationPending 属性设置为 true 时,我们可以结束操作。 ProgressChanged 事件可以显示操作的当前进度,因此您可以监视操作的进程。

RunWorkerCompleted 事件将会调用在后台线程上执行的异步操作执行完成时调用的事件处理程序。 在事件处理程序中,我们可以检查 IsCanceled 属性是否为 true,以判断操作是正常结束还是被取消。

示例2:使用异步操作和进度报告

下一个示例仍然是异步操作,但由于计算不同,我们需要一种不同的方法来计算进度。在这个示例中,我们计算质数。正在计算质数时,线程睡眠1ms,以便其他程序继续运行。该计算迭代10,000, 因此,我们需要对已完成的百分比进行测量。

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    int count = 0;
    for (int i = 2; i <= 10000; i++)
    {
        if (worker.CancellationPending)
        {
            e.Cancel = true;
            break;
        }

        bool isPrime = true;
        for (int j = 2; j < i; j++)
        {
            if (i % j == 0)
            {
                isPrime = false;
                break;
            }
        }

        if (isPrime)
        {
            count++;
            double percentage = (double)count / (double)10000 * 100;
            worker.ReportProgress((int)Math.Floor(percentage), count);
        }

        Thread.Sleep(1);
    }
}

void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
    labelPercentage.Text = e.ProgressPercentage.ToString() + "%";
    labelCount.Text = e.UserState.ToString();
}

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("质数计算被取消。");
    }
    else if (e.Error != null)
    {
        MessageBox.Show("质数计算异常: " + e.Error.Message);
    }
    else
    {
        labelCount.Text = "质数总共为:" + e.Result.ToString();
        MessageBox.Show("质数计算已完成!");
    }
}

void buttonStart_Click(object sender, EventArgs e)
{
    buttonStart.Enabled = false;
    buttonCancel.Enabled = true;
    progressBar.Value = 0;
    labelPercentage.Text = "0%";
    labelCount.Text = "总数为:0";
    backgroundWorker.RunWorkerAsync();
}

void buttonCancel_Click(object sender, EventArgs e)
{
    if (backgroundWorker.IsBusy)
    {
        backgroundWorker.CancelAsync();
    }
}

在这个示例中,使用异步操作计算质数,并使用一个进度条显示操作的进度。当 BackgroundWorker 的 ReportProgress 方法被调用时,ProgressChanged 事件就会触发, 其中, ReportProgress 用来实现异步报告进度,可以带有一个当前进度百分比,和一个可选的用户状态对象,以显示进度。 运行完成后,我们会调用 RunWorkerCompleted 事件处理程序,它在异步操作运行并完成时调用。在事件处理程序中,我们可以检查 IsCanceled 属性是否为 true,以判断操作是正常结束还是被取消。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# BackgroundWorker用法详解 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • asp.net 验证码生成和刷新及验证

    asp.net验证码生成 在asp.net中生成验证码需要使用Captcha控件,该控件可以生成图片验证码并且可以自定义验证码字符集合,大小,颜色等等。 首先需要在aspx页面中引入该控件: <%@ Register Assembly="System.Web.UI.WebControls" Namespace="Syste…

    C# 2023年6月1日
    00
  • Unity Shader实现玻璃材质效果

    下面是Unity Shader实现玻璃材质效果的完整攻略: 第一步:创建一个透明材质球 首先,在Unity中创建一个透明材质球。在Unity菜单栏中选择Assets->Create->Material,右键选择Rename,将Material更名为“Glass”。 第二步:设置Glass的Shader为Transparent 在“Glass”的I…

    C# 2023年6月3日
    00
  • WPF Slider滑动条的颜色修改方法

    下面是详细讲解“WPF Slider滑动条的颜色修改方法”的完整攻略。 1. 修改Slider的颜色 在WPF中,可以通过修改Slider的控件模板(Template)来自定义滑动条的颜色。具体步骤如下: 在XAML文件中找到要修改的Slider控件。 设置Slider的控件模板。 例如,为Slider设置一个红色的滑动条,可以这样写: <Slider…

    C# 2023年6月6日
    00
  • .NET1.0版本中的异步编程模型(APM)

    .NET 1.0版本中的异步编程模型(APM) 在 .NET 1.0 版本中,使用异步编程模型(Async Programming Model,APM)可以轻松实现异步操作,其主要思想是通过非阻塞式编程模型来提高程序性能和响应时间。通过将耗时操作放入单独的线程中,并在处理完成后通知调用线程,提高了程序并发性和响应时间。 异步编程模型的基本组成部分 异步编程模…

    C# 2023年6月3日
    00
  • C#集合本质之堆栈的用法详解

    C#集合本质之堆栈的用法详解 什么是堆栈(Stack)? 堆栈是一种特殊的数据结构,它的特点是后进先出(Last In First Out, LIFO)。堆栈通常是通过数组或链表实现的,操作系统在进程调度、函数调用、表达式求值等方面广泛应用了堆栈。 C#堆栈的实现 C#中实现堆栈的数据结构有两种,一种是System.Collections.Stack类,另一…

    C# 2023年6月7日
    00
  • JWT.net 操作实践方法

    JWT.net 操作实践方法 JSON Web Token(JWT)是一种基于JSON格式的Web Token标准,用于在不信任的环境下对用户进行身份验证和授权。JWT.net是一个C#中的JWT实现库,本篇文章将介绍如何使用JWT.net进行JWT生成、验证、签名等操作。 安装 可以通过NuGet包管理器或者命令行安装JWT.net: Install-Pa…

    C# 2023年5月31日
    00
  • C#自定义事件及用法实例

    C#自定义事件及用法实例 在C#编程中,事件是编写高效程序不可缺少的一个重要部分。在C#中,可以使用内置的事件(System.EventHandler)来对事件进行处理。同时,也可以使用自定义的事件来实现特定要求的事件处理。 本文将详细介绍C#自定义事件及用法实例,帮助读者更好地理解事件机制并掌握自定义事件的应用。 什么是C#自定义事件 自定义事件是基于内置…

    C# 2023年6月1日
    00
  • C# CultureInfo之常用InvariantCulture案例详解

    C# CultureInfo之常用InvariantCulture案例详解 什么是CultureInfo CultureInfo是用于表示特定区域性的类。在C#中,可以使用CultureInfo类来处理不同语言和国家的格式。 使用CultureInfo可以将数字、日期、货币和字符串等数据格式转换为不同的语言和国家的格式。 InvariantCulture I…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部