C#多线程编程笔记(3.5)-使用BackgroundWorker组件

近来在学习Eugene Agafonov编写的《C#多线程编程实战》(译),做些笔记也顺便分享一下^-^

本实例演示了另一种异步编程的方式,即使用BackgroundWorker组件。借助于该对象,可以将异步代码组织为一系列事件及事件处理器

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

namespace 使用BackgroundWorker组件
{
    class Program
    {
        static void Main(string[] args)
        {
            var bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.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);
        }

        static void Worker_DoWork(object sender,DoWorkEventArgs e)
        {
            Console.WriteLine("DoWork thread pool thread id: {0}", Thread.CurrentThread.ManagedThreadId);
            var bw = (BackgroundWorker)sender;
            for (int i = 1; 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;
        }

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

        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);
            }
        }
    }
}

程序运行结果如下:


当程序启动时,创建了一个BackgroundWorker组件的实例。显式地指出该后台工作线程支持取消操作及该操作进度的通知。

之后我们使用了事件机制,订阅了三个事件,事件的具体用法不予赘述,当这些事件发生时,将调用相应的事件处理器。

我们一共定义了三个事件。第一个是oWork事件,当一个后台工作对象通过RunWorkerAsync方法启动一个异步操作时,该事件处理器将被调用。该事件处理器将会运行在线程池中。如果需要取消操作,则这里是主要的操作点来取消执行。同时也可以提供该操作的运行进程信息。最后,得到结果后,将结果设置给事件参数,然后RunWorkerCompleted事件处理器将被调用。在该方法中,可以知道操作是成功完成,还是发生错误还是被取消。

基于此,BackgroundWorker组件实际上被使用于Windows窗体应用程序中。该实现通过后台工作事件处理器的代码可以直接与UI控制器交互。与线程池中的线程与UI控制器交互的方式相比较,使用BackgroundWorker组件的方式更加自然和好用。

猜你喜欢

转载自blog.csdn.net/qq_35445058/article/details/80780847