winform多线程组件BackgroundWorker使用

WinForm多线程组件BackgroundWorker是一种方便且易于使用的组件,可以使多线程编程变得更加容易。以下是使用BackgroundWorker时需要注意的事项:

什么是BackgroundWorker

BackgroundWorker是一个WinForm多线程组件,可以在后台执行操作,通常可以将花费时间很长的任务放在后台线程中执行,而不会阻塞UI线程。 BackgroundWorker组件提供了三个事件:DoWork、ProgressChanged和RunWorkerCompleted。当你在后台执行操作时,可以将进度信息报告给UI线程,并在运行结束时调用RunWorkerCompleted事件。

创建BackgroundWorker

在设计模式下,你可以从工具菜单中选择BackgroundWorker组件并将其拖拽到WinForm窗体中。然后,通过检查属性窗口上的worker属性来设置背景工作器的属性,例如:WorkerReportsProgress属性(指示是否应在进度更改时通知UI线程)和WorkerSupportsCancellation属性(指示背景工作器是否支持取消操作)。或者,你可以在代码中直接创建BackgroundWorker实例,例如:

private BackgroundWorker _worker = new BackgroundWorker();

启动BackgroundWorker

要启动BackgroundWorker,你可以通过调用RunWorkerAsync方法,例如:

_worker.RunWorkerAsync();

你可以选择将StartNewWorker方法绑定到按钮的Click事件上,例如:

private void btnStartWorker_Click(object sender, EventArgs e)
{
    _worker.RunWorkerAsync();
}

实现DoWork事件

DoWork事件是BackgroundWorker中最重要的事件,必须在该事件中编写实际要执行的代码。该事件会在后台线程上执行,因此不能直接从DoWork事件访问UI元素。如果需要更新进度,可以调用ReportProgress方法,向UI线程报告进度,例如:

private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
        Thread.Sleep(100);
        _worker.ReportProgress(i);
    }
}

更新UI元素

如果需要在DoWork事件中更新UI元素,可以将ReportProgress方法的UserState属性设置为要发送给UI线程的对象。通过ReportProgress方法发送对象到UI线程,可以在ProgressChanged事件中读取该对象并更新UI元素,例如:

private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    lblPercentComplete.Text = e.ProgressPercentage.ToString() + "%";
    progressBar.Value = e.ProgressPercentage;
    if (e.UserState != null)
    {
        string message = (string)e.UserState;
        MessageBox.Show(message);
    }
}

实现RunWorkerCompleted事件

在DoWork事件完成后,RunWorkerCompleted事件将被引发。在该事件中,您可以执行任何喜欢的操作,并在需要时检查错误并从异常中提取错误消息。例如:

private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("任务已取消。");
    }
    else if (e.Error != null)
    {
        MessageBox.Show("错误:" + e.Error.Message);
    }
    else
    {
        MessageBox.Show("任务已完成。");
    }
}

示例1:简单的后台操作

在此示例中,我们将会显示一个包含一个按钮和一个进度条的窗体。单击按钮将在后台线程上执行任务,并在进度条上报告进度。当任务完成时,我们将在UI线程上显示消息。

private void btnStartWorker_Click(object sender, EventArgs e)
{
    _worker.WorkerReportsProgress = true;
    _worker.WorkerSupportsCancellation = true;
    _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
    _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
    _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
    _worker.RunWorkerAsync();
}

private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
        Thread.Sleep(100);
        _worker.ReportProgress(i);
    }
    e.Result = "任务已完成";
}

private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
    lblPercentComplete.Text = e.ProgressPercentage.ToString() + "%";
}

private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("任务已取消");
    }
    else if (e.Error != null)
    {
        MessageBox.Show("错误:" + e.Error.Message);
    }
    else
    {
        string result = (string)e.Result;
        MessageBox.Show(result);
    }
}

示例2:取消后台操作

此示例演示了如何取消后台操作。当用户单击“取消”按钮时,将取消后台任务。当任务被取消时,我们将在UI线程上显示消息。

private void btnStartWorker_Click(object sender, EventArgs e)
{
    _worker.WorkerReportsProgress = true;
    _worker.WorkerSupportsCancellation = true;
    _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
    _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
    _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
    _worker.RunWorkerAsync();
}

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

private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
        if (_worker.CancellationPending)
        {
            e.Cancel = true;
            return;
        }
        Thread.Sleep(100);
        _worker.ReportProgress(i);
    }
    e.Result = "任务已完成";
}

private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
    lblPercentComplete.Text = e.ProgressPercentage.ToString() + "%";
}

private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("任务已取消");
    }
    else if (e.Error != null)
    {
        MessageBox.Show("错误:" + e.Error.Message);
    }
    else
    {
        string result = (string)e.Result;
        MessageBox.Show(result);
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:winform多线程组件BackgroundWorker使用 - Python技术站

(1)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • C#中Activator.CreateInstance()方法用法分析

    C#中Activator.CreateInstance()方法用法分析 前言 C#中 Activator.CreateInstance() 方法是一种动态创建实例的方法。在实际项目中,我们常常需要动态加载程序集并创建其中的类型对象。这时,Activator.CreateInstance()方法就可以起到很好的作用。 方法说明 Activator.Create…

    C# 2023年5月31日
    00
  • 详解C#中通过委托来实现回调函数功能的方法

    详解C#中通过委托来实现回调函数功能的方法: 1.委托和回调函数的概念 在C#中,委托(Delegate)是一种类型,它是一种指向方法的引用,可以将方法作为参数传递。回调函数(Callback Function)是一种方法,它可以作为参数传递给其他方法,然后在适当的时候被调用。 2.使用委托实现回调函数 在C#中,可以使用委托来实现回调函数的功能。首先定义一…

    C# 2023年6月1日
    00
  • ASP.NET(C#) String, StringBuilder 与 StringWriter性能比较

    ASP.NET是一种广泛使用的Web应用程序框架,C#是一种强类型面向对象的编程语言。在开发ASP.NET应用程序时,我们常常需要使用字符串操作,其中包括String、StringBuilder和StringWriter这三种不同的类型。这三种类型有着不同的性能特点,需要根据具体的情况来选择使用。 1. String String是C#中常用的字符串类型,它…

    C# 2023年6月3日
    00
  • ASP.NET Core Mvc中空返回值的处理方法详解

    让我来详细讲解一下关于ASP.NET Core Mvc中空返回值的处理方法。 问题描述 在ASP.NET Core Mvc中,我们在控制器方法中通常使用返回类型为ActionResult或者是ActionResult。但是在某些情况下,我们希望不返回任何数据,或者只返回HTTP状态码。这时候就需要处理空返回值的情况了。 解决方案 在ASP.NET Core …

    C# 2023年5月31日
    00
  • C#延迟执行方法函数实例讲解

    C#延迟执行方法函数实例讲解 什么是延迟执行 延迟执行是指在需要的时候才会进行真正的计算或执行,它可以提高程序的执行效率,在一些需要消耗大量资源或时间的情况下尤为重要。 C#中的延迟执行 C#中延迟执行可以通过Lambda表达式、Func和Action委托等方式实现。 Lambda表达式实现延迟执行 Lambda表达式是一种简单、紧凑的语法形式,可以在需要的…

    C# 2023年6月1日
    00
  • 详解C#数据类型及其转换

    我来为您详细讲解“详解C#数据类型及其转换”的完整攻略。 一、数据类型及其分类 在C#编程中,数据类型是不可或缺的一部分。C#的数据类型可以分为以下几类: 值类型:这类数据类型是直接存储在堆栈中的,默认情况下分配在栈上,当超出范围时自动释放,这些类型包括:整型、浮点型、双精度浮点型、字符型、布尔型以及枚举类型等。 引用类型:这类数据类型存储在堆中,生成对象时…

    C# 2023年5月15日
    00
  • log4net配置和使用方法分享

    下面是“log4net配置和使用方法分享”的完整攻略。 1. 简介 log4net是一个强大的.NET日志记录库,它允许您记录到多个输出目标,包括文件、控制台、数据库、电子邮件和其他自定义输出目标。log4net是Apache Software Foundation的一个项目,它和另一个流行的Java日志记录库log4j很相似。在本文中,我们将学习如何配置和…

    C# 2023年5月31日
    00
  • c# 操作word写入特殊字符的实例

    下面是关于“c# 操作word写入特殊字符的实例”完整攻略。 1. 确定写入的特殊字符 在使用C#操作Word写入特殊字符之前,必须确定写入的特殊字符是什么。常见的特殊字符包括制表符、回车、换行、页码、分隔符等。特殊字符的插入方法不同,因此确定特殊字符种类非常重要。 2. 打开Word文档 在C#中操作Word的第一步是打开Word文档。可以通过以下代码来打…

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