孤独的猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

  可能您会觉得使用委托的BeginInvoke方法实现异步操作太过繁琐了,我们在多数情况下仅仅是希望启动一个线程进行一些工作,完成后执行一个回调函数就OK了,并没有太多其他的需求。有没有更方便的方法实现异步操作呢?就像事件那样简单,注册一个异步操作函数,待函数执行完毕后再自动执行一个回调函数,而异步线程启动、运行、结束之类的操作都由程序自动完成。答案是有的,这就是System.ComponentModel.BackgroundWorker类的功能。

  我们先看代码:

复制代码
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Threading;

namespace ThreadTest
{
class Program
{
//创建BackgroundWorker对象
static BackgroundWorker bw =new BackgroundWorker();
//同步信号
static AutoResetEvent av =new AutoResetEvent(false);

staticvoid Main(string[] args)
{
//显示主线程ID
Console.WriteLine("主线程ID为:"+ Thread.CurrentThread.ManagedThreadId);

//添加异步操作的事件函数
bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
//添加异步操作完成后的回调函数
bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

//启动异步操作,并为其传递事件参数
bw.RunWorkerAsync("我在工作呢!");

//等待异步操作完成
av.WaitOne();

Console.ReadKey();
}

//异步操作工作函数
staticvoid bw_DoWork(object sender, DoWorkEventArgs e)
{
//显示异步工作线程ID
Console.WriteLine("异步工作线程ID为:"+ Thread.CurrentThread.ManagedThreadId);

//休眠1秒,模拟长时间工作
Thread.Sleep(1000);

//显示事件传入的参数
Console.WriteLine(e.Argument);
//写入异步操作的结果
e.Result ="工作顺利完成";
}

//异步操作完成回调函数
staticvoid bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//显示异步工作完成线程ID
Console.WriteLine("异步工作完成线程ID为:"+ Thread.CurrentThread.ManagedThreadId);

//显示异步操作结果
Console.WriteLine(e.Result);

//发送同步信号
av.Set();
}
}
}
复制代码

  程序运行的结果如下图:

  从运行结果我们可看出,异步操作的线程与主线程各自处于不同线程,实现了异步操作。

  简要解释一下代码:

  1. 创建一个BackgroundWorker类。

  2. 为该类的DoWork事件注册异步操作工作函数。

  3. 为该类的RunWorkerCompleted事件注册异步操作完成后的回调函数。

  4. 执行该类的RunWorkerAsync方法,启动异步操作。可为该方法指定一个object类型的参数,该参数被传递给异步操作工作函数,用于存储一些工作函数所需的必要信息。

  5. 在异步操作工作函数中可用DoWorkEventArgs参数的Argument属性读取由主线程存入的数据;可用该参数的Result属性存入异步操作的结果,该结果会被传递给异步操作完成后的回调函数。

  6. 回调函数可使用传入的RunWorkerCompletedEventArgs参数的Result属性接收工作函数中存入的操作结果,并进行相关处理。

posted on 2012-11-28 09:57  孤独的猫  阅读(1698)  评论(0)    收藏  举报