C#使用BackgroundWorker控件

在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示,必要时还要控制后台线程中断当前操作。

在.net中,提供了一个组件BackgroundWorker就是专门解决这个问题的。BackgroundWorker类允许在单独的专用线程上运行操作。 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面(UI)似乎处于停止响应状态。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题。

程序执行步骤:

  • 1、调用BackgroundWorker的RunWorkerAsync()方法,如果后台操作需要参数,在调用RunWorkerAsync()方法时给出参数,在DoWork事件处理程序内部,可以从DoWorkEventArgs.Argument属性中提取该参数。
  • 2、执行DoWork事件,后台需要执行的代码放到DoWork事件里面执行。当调用RunWorkerAsync()方法时,BackgroundWorker通过触发DoWork事件,开始执行后台操作

显示后台操作进度:

为了显示后台操作的执行进度,首先要使WorkerReportsProgress等于true,然后调用BackgroundWorker的ReportProgress()方法,通过它传递操作完成的进度值,此外,该方法触发ProgressChanged事件,在此事件中,通过ProgressChangedEventArgs的实例,接收到主线程传递过来的参数。

取消后台操作:

为了使 BackgroundWorker 可以取消后台正在执行的操作,首先要把属性WorkerSupportsCancellation 的值设置为 true。接着调用CancelAsync()方法,该方法使得属性CancellationPending 为true,利用CancellationPending 属性,可以判断是否取消后台异步操作。

后台操作完成后,反馈给用户:

当后台操作完成以后,无论是completed 还是cancelled,RunWorkerCompleted()事件都会被触发,通过此方法可以将后台操作的完成结果反馈给用户。RunWorkerCompleted 事件处理函数会在DoWork 事件处理函数返回后被调用。通过它我们可以进行一些运算结束后的操作,比如禁用取消按钮,异常处理,结果显示等。注意,如果想要拿到e.Result,您需要在BGWorker_DoWork方法中设置 e.Result属性另外,通过RunWorkerCompletedEventArgs实例的Cancelled 属性,以判断是否是Cancel操作使得后台操作终止;

从后台操作返回值

在执行DoWork事件时DoWorkEventArgs实例的Result属性,返回值到用户;在RunWorkerCompleted事件里,RunWorkerCompletedEventArgs 实例的Result属性接收值;

创建BackgroundWorkerDemo例子:

  • 1.新建一个windows窗体应用程序,如:BackgroundWorkerDemo
  • 2.拖一个ProgressBar(进度条)和一个BackgroundWorker控件到Form窗体上,界面如图:

后台代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace BackgroundWorkerDemo
{
    public partial class FrmDemo : Form
    {
        //设置生成临时文件的路径
        static string strSaveDir = @"F:\培训";
        public FrmDemo()
        {
            InitializeComponent();

            //显示后台操作的执行进度
            this.bgWork.WorkerReportsProgress = true;
            //可以取消后台正在执行的操作
            this.bgWork.WorkerSupportsCancellation = true;
        }

        /// <summary>
        /// 开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Start_Click(object sender, EventArgs e)
        {
            if (Directory.Exists(strSaveDir) == false)
            {
                return;
            }
            btn_Start.Enabled = false;
            int count = Convert.ToInt32(this.txt_File.Text.ToString().Trim());
            //设置进度条
            this.proBar.Minimum = 0;
            this.proBar.Maximum = count;
            this.proBar.Value = this.proBar.Minimum;
            //开始执行异步线程,进行后台操作,给后台传递参数
            this.bgWork.RunWorkerAsync(count);
        }

        /// <summary>
        /// 后台操作要处理的任务代码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bgWork_DoWork(object sender, DoWorkEventArgs e)
        {
            //获取从RunWorkerAsync()方法里面传递的参数的值
            int fileCount= Convert.ToInt32(e.Argument);
            Random rand = new Random();
            byte[] buffer = new byte[2048];
            for (int i = 0; i < fileCount; i++)
            {
                try
                {
                    string strFileName = Path.Combine(strSaveDir, i.ToString() + ".tmp");
                    using (var stream = File.Create(strFileName))
                    {
                        int n = 0;
                        int maxByte = 8 * 1024 * 1024;
                        while (n < maxByte)
                        {
                            rand.NextBytes(buffer);
                            stream.Write(buffer, 0, buffer.Length);
                            n += buffer.Length;
                        }
                    }
                }
                catch (Exception ex)
                {
                    continue;
                }
                finally
                {
                    //报告进度
                    this.bgWork.ReportProgress(i + 1);
                    Thread.Sleep(100);
                }

                //判断是否取消了后台操作
                if (bgWork.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                //设置返回值
                e.Result = 234;
            }
        }

        /// <summary>
        /// 更新前台界面进度条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bgWork_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //获取异步任务的进度百分百
            int val = e.ProgressPercentage;
            this.label2.Text = string.Format("已经生成{0}个文件", val);
            //进度条显示当前进度
            this.proBar.Value = val;
        }

        /// <summary>
        /// 后台操作完成,向前台反馈信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bgWork_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btn_Start.Enabled = true;
            //用户取消操作(e.Cancelled==true,表示异步操作已被取消)
            if (e.Cancelled)
            {
                MessageBox.Show("用户取消后台操作", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("操作完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                //接收返回值
                int result = (int)e.Result;

                MessageBox.Show("返回值:" + result);
            }
        }

        /// <summary>
        /// 取消
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Cancle_Click(object sender, EventArgs e)
        {
            //调用CancelAsync(),取消挂起的后台操作
            this.bgWork.CancelAsync();
        }
    }
}

运行界面:

操作完成界面:

接收返回值:

取消后台操作:

到此这篇关于C#使用BackgroundWorker控件的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • c# BackgroundWorker组件的作用

    当构建一个图形化的Windows Form桌面应用程序并且需要执行在应用程序主UI线程之外的线程中长时间的任务时,BackgroundWorker类就很有用了. 要使用BackgroundWorker,我们只需要告诉它希望在后台执行那个方法并且调用RunWorkerAsync()即可 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(ob

  • WinForm中BackgroundWorker控件用法简单实例

    本文实例讲述了WinForm中BackgroundWorker控件用法.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Win

  • asp.net BackgroundWorker之在后台下载文件

    示例: 下面的代码示例演示如何使用 BackgroundWorker 组件从 URL 加载 XML 文件.用户单击"下载"按钮时,Click 事件处理程序将调用 BackgroundWorker 组件的 RunWorkerAsync 方法来启动下载操作.在下载过程中,将禁用该按钮,然后在下载完成后再启用该按钮.MessageBox 将显示文件的内容. 复制代码 代码如下: using System; using System.Collections.Generic; using Sys

  • c#异步操作后台运行(backgroundworker类)示例

    c#异步操作,BackgroundWorker类的使用,可以在后台运行需要的代码逻辑. 复制代码 代码如下: using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Windows.Fo

  • c# BackgroundWorker使用方法

    在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应.解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作.新建线程可以用 Thread 类,可以实现多线程同时操作.简单的方法可以通过 BackgroundWorker 类实现. BackgroundWorker 可以用来更新UI界面,但是通常用来Progressbar(进度条)控件 例如更新UI private void Form1_Load(object

  • 简单使用BackgroundWorker创建多个线程的教程

    BackgroundWorker是一个非常不错的线程控件,能避免界面假死,让线程操作你想要做的事,它学习起来很简单,但是能实现很强大的功能.发布这篇文章的目的是将最近学习到的共享出来,大家交流一下,当然我也是菜鸟,在这里你将学习到BackgroundWorker简单使用,停止,暂停,继续等操作,BackgroundWorker比起Thread和ThreadPool要简单太多,为了更方便在实际应用中使用,我使用的是winform,没有使用控制台程序. 在UI界面里拖动一个button和richTe

  • C#在后台运行操作(BackgroundWorker用法)示例分享

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示,必要时还要控制后台线程中断当前操作. 以前,类似的应用会比较麻烦,需要写的代码较多,也很容易出现异常.在.net中,提供了一个组件BackgroundWorker就是专门解决这个问题的.BackgroundWorker类允许在单独的专用线程上运行操作. 耗时的操作(如下载和数据库事务)在长时间运行

  • C# BackgroundWorker组件学习入门介绍

    一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能. BackgroundWorker类允许您在单独的专用线程上运行操作.  耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态. 如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker类方便地解决问题(MSDN). 若要在后台执行耗时的操作,请创建一个

  • C#中BackgroundWorker类用法总结

    目录 1.属性: WorkerReportsProgress  WorkerSupportsCancellation  CancellationPending  IsBusy  2.方法: RunWorkerAsync()  ReportProgress(IntpercentProgress)  CancelAsync()  3.事件: DoWork ProgressChanged RunWorkerCompleted 4.附源代码: 查询了一下MSDN文档,其中微软就BackgroundWor

  • C# BackgroundWorker使用教程

    查询了一下MSDN文档,其中微软就BackgroundWorker类的功能有这么一个描述(英文的,根据个人理解翻译):BackgroundWorker类允许您在单独的线程上执行某个可能导致用户界面(UI)停止响应的耗时操作(比如文件下载数据库事务等),并且想要一个响应式的UI来反应当前耗时操作的进度. 可以看的出来,BackgroundWorker组件提供了一种执行异步操作(后台线程)的同时,并且还能妥妥的显示操作进度的解决方案.于是乎,我便深入的了解了一下BackgroundWorker类.针

  • C#中backgroundworker的使用教程

    介绍: 根据MSDN介绍: BackgroundWorker 类允许您在单独的专用线程上运行操作. 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态. 如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题. 若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件. 可以通过编程方式创建 Background

  • C#使用后台线程BackgroundWorker处理任务的总结

    在一些耗时的操作过程中,在长时间运行时可能会导致用户界面 (UI) 处于停止响应状态,用户在这操作期间无法进行其他的操作,为了不使UI层处于停止响应状态,我们倾向推荐用户使用BackgroundWorker来进行处理,这个后台的线程处理,可以很好的实现常规操作的同时,还可以及时通知UI,包括当前处理信息和进度等,这个BackgroundWorker的处理在百度里面也是有很多使用的介绍,本篇随笔主要是做一些自己的使用总结,希望也能给读者提供一个参考. 在使用BackgroundWorker的过程中

  • C#中backgroundWorker类的用法详解

    1.在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应.解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作.新建线程可以用 Thread 类,可以实现多线程同时操作.简单的方法可以通过 BackgroundWorker 类实现. BackgroundWorker 可以用来更新UI界面,但是通常用来Progressbar(进度条)控件 例如更新UI private void Form1_Load(objec

  • C# BackgroundWorker用法详解

    在C#程序中,经常会有一些耗时较长的CPU密集型运算,如果直接在 UI 线程执行这样的运算就会出现UI不响应的问题.解决这类问题的主要途径是使用多线程,启动一个后台线程,把运算操作放在这个后台线程中完成.但是原生接口的线程操作有一些难度,如果要更进一步的去完成线程间的通信就会难上加难. 还好 .NET 类库中提供了一个叫做 BackgroundWorker 的类可以比较优雅的解决这类问题.虽然BackgroundWorker 类使用起来比较简单,但其中还是有一些需要注意的细节,下面我们就通过 d

随机推荐