C#沉淀-异步编程 四

本文深入探讨C#的异步编程,重点讲解BackgroundWorker类的使用,包括其主要成员、事件处理及示例。同时,文章介绍了并行循环的Parallel.ForEach,展示了如何在多核处理器上实现任务并行。此外,还讨论了其他异步编程模式,如BeginInvoke、EndInvoke、回调模式和轮询模式,以及Timer类的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BackgroundWorker类

async/await特性适合那些需要在后台完成的不相关的小任务,有时候,需要另建一个线程,在后台持续运行以完成某项工作,并不时地与主线程进行通信,BackgroundWorker类就是为此而生。

BackgroundWorker类的主要成员
  • 属性
    • WorkerReportsProgress 设置后台任务是否可以把它的进度汇报给主线程
    • WorkerSupportsCancellation 是否支持从主线程取消
    • IsBusy 检查后台任务是否正在运行
    • CancelationPending 状态值,布尔类型
  • 方法
    • RunWorkerAsync() 获取后台线程并执行DoWork事件处理程序
    • CancelAsync() 把CancellationPending属性设置为true。DoWork事件处理程序需要检查这个属性来决定是否应该停止处理
    • ReportProgress() DoWork工作的时候向主线程汇报进度
  • 事件
    • DoWork 在后台线程开始的时候触发
    • ProgressChanged 在后台任务汇报状态的时候触发
    • RunWorkerCompleted 在后台工作线程退出的时候触发

使用示例:

using System.Threading;
using System.Windows;
using System.ComponentModel;

namespace WpfForAsync
{
   
   
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
   
   
        // 首先需要创建BackgroundWorker对象
        BackgroundWorker bgWorker = new BackgroundWorker();

        public MainWindow()
        {
   
   
            InitializeComponent();

            // 设置BackgroundWorker属性
            // WorkerReportsProgress设置工作线程为主线程汇报进度
            bgWorker.WorkerReportsProgress = true;
            // 设置支持从主线程取消工作线程
            bgWorker.WorkerSupportsCancellation = true;

            // 连接BackgroundWorkder对象的处理程序
            //DoWork是必须的
            bgWorker.DoWork += BgWorker_DoWork;
            //ProgressChanged与RunWorkerCompleted这两个是可选的
            bgWorker.ProgressChanged += BgWorker_ProgressChanged;
            bgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
        }

        private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
   
   
            progressBar.Value = 0;

            if (e.Cancelled)
            {
   
   
                MessageBox.Show("Process was cancelled.", "Process Cancelled");
            }
            else
            {
   
   
                MessageBox.Show("Process completed normally.", "Process Completed");
            }
        }

        private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
   
   
            progressBar.Value = e.ProgressPercentage;
        }

        /// <summary>
        /// 这里是希望在后台工作的代码 
        /// 它是在独立的线程中执行的
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
   
   
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 0; i <= 10; i++)
            {
   
   
                if (worker.CancellationPending)
                {
   
   
                    e.Cancel = true;
                    break;
                }
                else
                {
   
   
                    /// 后台线程通过调用ReportProgress方法与主线程通信。
                    /// 届时将触发ProgressChanged事件
                    /// 主线程可以处理附加到ProgressChanged事件上的处理程序
                    worker.ReportProgress(i * 10);
                    Thread.Sleep(500);
                }
            }
        }

        private void btnProcess_Click(object sender, RoutedEventArgs e)
        {
   
   
            if (!bgWorker.IsBusy)
            {
   
   
                //主线程调用RunWorkerAsync的时候,会触发DoWork事件
                bgWorker.RunWorkerAsync();
            }
        }

        private void progressBar_Click(object sender, RoutedEventArgs e)
        {
   
   
            // 通知后台线程退出
            // 此时会将后台线程类的CancellationPending属性设置为true
            // DoWork事件处理程序会定期检查CancellationPending确定是否要退出
            // 如果后台线程退出,则会触发RunWorkerCompleted事件
            bgWorker.CancelAsync();
        }
    }
}

这是一个WPF程序,前端代码与上一节的一样,后端代码使

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值