使用线程池(7)

使用BackgroundWorker组件

简介

使用BackgroundWorker组件,将代码组织为一系列的事件及事件处理器。

以下是代码实践:

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

namespace 使用BackgroundWorker组件
{
    internal class Program
    {
        private static void Main()
        {
            var bw = new BackgroundWorker
            {
                WorkerReportsProgress = true,//启用进度报告功能
                WorkerSupportsCancellation = true//启用异步操作取消功能
            };

            bw.DoWork += Worker_DoWork;
            bw.ProgressChanged += Worker_ProgressChanged;
            bw.RunWorkerCompleted += Worker_Completed;

            bw.RunWorkerAsync();
            Console.WriteLine("Press C to cancel work");
            do
            {
                if (Console.ReadKey(true).KeyChar=='c')
                {
                    bw.CancelAsync();//请求取消异步操作
                }
            } while (bw.IsBusy);
        }

        private static void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("DoWork thread pool id: {0}; Is thread pool thread: {1}",
                Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread);
            var bw = (BackgroundWorker) sender;

            for (var i = 0; i <=100; i++)
            {
                if (bw.CancellationPending)//判断是否有取消操作的请求
                {
                    e.Cancel = true;//取消异步操作
                    return;
                }

                if (i%10==0)
                {
                    bw.ReportProgress(i);//报告进度
                }

                Thread.Sleep(TimeSpan.FromSeconds(0.1));
            }
            e.Result = 42;
        }

        private static void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine("{0}% completed. Progress thread pool thread id: {1}",e.ProgressPercentage,
                Thread.CurrentThread.ManagedThreadId);
        }

        //异步操作完成或取消后触发的事件程序
        private static void Worker_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("Completed thread pool thread id: {0}",Thread.CurrentThread.ManagedThreadId);
            if (e.Error != null)
            {
                Console.WriteLine("Exception {0} has occured.",e.Error.Message);
            }
            else if (e.Cancelled)
            {
                Console.WriteLine("Operation has been canceled.");
            }
            else
            {
                Console.WriteLine("The answer is: {0}",e.Result);
            }
        }
    }
}


总结

  1. 事件的处理器运行在线程池中;
  2. 这种方式称为基于事件的异步模式(Event-based Asynchronous Pattern,简称EAP)。这是历史上第二种用来构造异步程序的方式,现在更推荐使用TPL

备注:学习《Multithreading in C# 5.0 Cookbook》Eugene Agafonov著的总结,以备日后查询。

posted on 2017-09-23 09:55  五月槐花  阅读(65)  评论(0编辑  收藏  举报

导航