winform多线程组件BackgroundWorker使用

yizhihongxing

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#委托与事件(详解)

    C#委托与事件(详解) 什么是委托? 在C#中,委托是一个类,用于指向和调用一个或多个方法。可以将委托看做是方法的类型。通过委托,我们可以在运行时确定要调用哪个方法,而无需提前确定调用哪个方法。 如何定义委托? 在C#中,委托的定义非常简单,只需使用delegate关键字即可。 delegate 返回类型 委托名称(参数列表); 其中, 返回类型:委托指向方…

    C# 2023年6月1日
    00
  • C# Math.Min()方法: 返回两个数中较小的那个数

    Math.Min()是C#中的一个数学函数,用于返回两个值中较小的一个值。以下是该函数的具体作用和使用方法: Math.Min()的作用 Math.Min()的作用是返回给定的两个参数中的最小值。Math.Min()函数可用于以下场景: 在比较两个数值大小的时候快速找到最小值。 在编写条件语句时,根据值的大小决定程序的执行路径。 Math.Min()的使用方…

    C# 2023年4月19日
    00
  • 关于C# dynamic装箱问题

    这里是关于C# dynamic装箱问题的完整攻略: 什么是C#装箱和拆箱 C#装箱和拆箱是指将值类型转换为引用类型,以及将引用类型转换为值类型的过程。在C#中,值类型是指整数、浮点数、字符等基本数据类型,而引用类型是指静态类型、类实例、数组对象等。 C#装箱和拆箱的问题 在C#中,对于动态类型dynamic,其底层是以object表示的。而对于值类型的dyn…

    C# 2023年5月14日
    00
  • C#图像处理的多种方法

    C#图像处理的多种方法 简介 C#是一种多用途面向对象编程语言,可用于开发Windows桌面应用程序,Web应用程序和游戏。C#在图像处理方面有很多库和方法可供使用。在本文中,我们将讨论一些常用的C#图像处理方法和库。 图像处理库 AForge.NET AForge.NET是一个开源的.NET图像和视频处理框架,包含了很多常用的图像处理算法,比如滤波器,边缘…

    C# 2023年6月8日
    00
  • DataReader不能使用using的详细示例

    当使用DataReader读取数据时,通常需要确保DataReader对象在使用完毕后可以被及时的释放。然而,如果在使用DataReader时使用了using语句块,则会抛出“Invalid attempt to call Read when reader is closed”异常,这是因为在销毁using语句块内的对象时,DataReader对象也会被关闭…

    C# 2023年5月15日
    00
  • ASP.NET Core静态文件使用教程(9)

    ASP.NET Core静态文件使用教程(9) 在本攻略中,我们将深入讲解如何在ASP.NET Core应用程序中使用静态文件,并提供两个示例说明。 什么是ASP.NET Core静态文件? ASP.NET Core静态文件是指应用程序中不需要动态生成的文件,例如图像、CSS、JavaScript和HTML文件等。这些文件可以直接从磁盘或CDN等外部资源加载…

    C# 2023年5月17日
    00
  • Asp.net 连接MySQL的实现代码[]

    下面是详细讲解”Asp.net 连接MySQL的实现代码[]”的完整攻略。 简介 在Asp.net网站中,连接MySQL数据库是常见需求。下面将分享Asp.net连接MySQL数据库的实现代码,本攻略将涵盖实现代码的示例,包括连接MySQL数据库和执行SQL语句。 连接MySQL数据库的实现代码 安装MySQL驱动 在Asp.net网站中,连接MySQL数据…

    C# 2023年5月31日
    00
  • Winform中Treeview实现按需加载的方法

    一、Winform中Treeview实现按需加载的方法 Winform中的Treeview控件非常适合用于显示树形结构的数据,但如果树的层次比较多或者数据比较庞大,一次性将所有数据全部加载到TreeView中显然不太现实,这时就需要实现按需加载的功能,即当需要展开树节点时,才动态地加载该节点下的子节点。 实现按需加载需要以下几个步骤: 1.设置TreeVie…

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