BackgroundWorker跨线程更新数据

14 篇文章 0 订阅

BackgroundWorker是一个中使用.net框架自己提供的更新ui的控件。这样不会造成跨线程处理数据的问题。
在C#中,BackgroundWorker控件允许在单独的专用线程上运行操作。 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面(UI)似乎处于停止响应状态。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用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.Threading.Tasks;
using System.Windows.Forms;

namespace BackgroundWorkerDemo
{
    public partial class Form1 : Form
    {
        private BackgroundWorker _demoBGWorker = new BackgroundWorker();
        public Form1()
        {
            InitializeComponent();
            this.progressBarSum.Maximum = 100;
            _demoBGWorker.WorkerReportsProgress = true;
            _demoBGWorker.WorkerSupportsCancellation = true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                btnCancel.Enabled = true;
                Console.WriteLine("button1_Click");
                Thread my_thread = Thread.CurrentThread;
                Console.WriteLine("button1_Click:" + my_thread.ManagedThreadId);
                if (_demoBGWorker != null)
                {
                    _demoBGWorker = null;
                    _demoBGWorker = new BackgroundWorker();
                }
                _demoBGWorker.WorkerReportsProgress = true;
                _demoBGWorker.WorkerSupportsCancellation = true;
                _demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;
                _demoBGWorker.DoWork += BGWorker_DoWork;
                _demoBGWorker.RunWorkerCompleted += BGWorker_RunWorkerCompleted;
                _demoBGWorker.RunWorkerAsync(100);
               
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
          
        }
        //开始工作事件
        private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("BGWorker_DoWork");
            Thread my_thread = Thread.CurrentThread;
            Console.WriteLine("BGWorker_DoWork:" + my_thread.ManagedThreadId);
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            int endNumber = 0;
            if (e.Argument != null)
            {
                endNumber = (int)e.Argument;
            }

            int sum = 0;
            for (int i = 0; i <= endNumber; i++)
            {
                sum += i;

                string message = "Current sum is: " + sum.ToString();
                //ReportProgress 方法把信息传递给 ProcessChanged 事件处理函数。
                //第一个参数类型为 int,表示执行进度。
                //如果有更多的信息需要传递,可以使用 ReportProgress 的第二个参数。
                //这里我们给第二个参数传进去一条消息。
                bgWorker.ReportProgress(i, message);
                Thread.Sleep(100);
                //在操作的过程中需要检查用户是否取消了当前的操作。
                if (bgWorker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
            }
        }
        //更新ui事件
        private void BGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine("BGWorker_ProgressChanged");
            Thread my_thread = Thread.CurrentThread;
            Console.WriteLine("BGWorker_ProgressChanged:" + my_thread.ManagedThreadId);
            //修改进度条的显示。
            this.progressBarSum.Value = e.ProgressPercentage;

            //如果有更多的信息需要传递,可以使用 e.UserState 传递一个自定义的类型。
            //这是一个 object 类型的对象,您可以通过它传递任何类型。
            //我们仅把当前 sum 的值通过 e.UserState 传回,并通过显示在窗口上。
            string message = e.UserState.ToString();
            this.labelSum.Text = message;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                Console.WriteLine("btnCancel_Click");
                Thread my_thread = Thread.CurrentThread;
                Console.WriteLine("btnCancel_Click:" + my_thread.ManagedThreadId);
                _demoBGWorker.CancelAsync();
                _demoBGWorker.ProgressChanged -= BGWorker_ProgressChanged;
                _demoBGWorker.DoWork -= BGWorker_DoWork; 
                _demoBGWorker.RunWorkerCompleted -= BGWorker_RunWorkerCompleted;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
        ///任务处理完触发事件
        private void BGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                Console.WriteLine("BGWorker_RunWorkerCompleted");
                Thread my_thread = Thread.CurrentThread;
                Console.WriteLine("BGWorker_RunWorkerCompleted:" + my_thread.ManagedThreadId);
                //如果用户取消了当前操作就关闭窗口。
                if (e.Cancelled)
                {
                    this.Close();
                }

                //计算已经结束,需要禁用取消按钮。
                this.btnCancel.Enabled = false;

                //计算过程中的异常会被抓住,在这里可以进行处理。
                if (e.Error != null)
                {
                    Type errorType = e.Error.GetType();
                    switch (errorType.Name)
                    {
                        case "ArgumentNullException":
                        case "MyException":
                            //do something.
                            break;
                        default:
                            //do something.
                            break;
                    }
                }

                //计算结果信息:e.Result
                //use it do something.
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用BackgroundWorker开启多线程时,需要先创建一个BackgroundWorker对象,然后设置DoWork事件处理程序。接着在主线程中调用BackgroundWorker的RunWorkerAsync方法,该方法将启动一个新线程并执行DoWork事件处理程序。可以通过设置BackgroundWorkerWorkerReportsProgress和WorkerSupportsCancellation属性,使其支持进度报告和取消操作。 以下是一个简单的示例代码,演示如何使用BackgroundWorker开启多线程: ```c# private BackgroundWorker worker; private void buttonStart_Click(object sender, EventArgs e) { // 创建BackgroundWorker对象 worker = new BackgroundWorker(); // 设置DoWork事件处理程序 worker.DoWork += new DoWorkEventHandler(worker_DoWork); // 设置支持进度报告和取消操作 worker.WorkerReportsProgress = true; worker.WorkerSupportsCancellation = true; // 启动新线程 worker.RunWorkerAsync(); } private void worker_DoWork(object sender, DoWorkEventArgs e) { // 执行耗时操作 for (int i = 1; i <= 100; i++) { // 发送进度报告 worker.ReportProgress(i); // 检查是否取消操作 if (worker.CancellationPending) { e.Cancel = true; return; } // 模拟耗时操作 Thread.Sleep(50); } } private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { // 更新进度条 progressBar1.Value = e.ProgressPercentage; } 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("操作已完成"); } } ``` 在上述代码中,buttonStart_Click事件处理程序中创建了一个BackgroundWorker对象,并设置DoWork事件处理程序、支持进度报告和取消操作。然后调用RunWorkerAsync方法启动新线程。在worker_DoWork事件处理程序中执行耗时操作,并发送进度报告。在worker_ProgressChanged事件处理程序中更新进度条。在worker_RunWorkerCompleted事件处理程序中检查是否取消操作或发生错误,并显示相应的消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值