最近在学习多线程方面的东西,打算在自己的小程序中尝试使用。所以也看了不少文章。关于BackgroundWork,其实去年就用Reflector大概看过,但是没有太懂,呵呵,今天看相关文章正好又碰到,所以就仔细看看。

 

一 异步编程

 

在开始介绍BackgroundWork之前还是废话一下,说说异步编程。异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机或查询数据库。异步操作在主应用程序线程以外的线程中执行。应用程序调用方法异步执行某个操作时,应用程序可在异步方法执行其任务时继续执行。

说到异步编程,就不能不说到多线程,他们之间的关系有时总是让人很迷惑。在学习的初期,你会觉得多线程和异步没有什么区别。我自己开一个新线程去执行一个任务和用异步执行一个任务感觉没什么区别。甚至分不清到底用什么。其实多线程是实现异步编程的一种方式,但不是实现异步编程的唯一方式。

如果学习过计算机体系结构就应该知道,CPU和外设之间通信有三种方式。比如请求打印机,当打印机没有准备好,这个时候就等待,直到打印机准备好,在执行操作,这个叫程序查询方式。但因为外设速度慢,浪费CPU时间;后来出现了硬件中断。在等待打印机的过程中,CPU分配给其他进程,当打印机准备好了,则发一个硬件中断,通知CPU打印。这样有效的提高了CPU的效率,但是频繁的中断和进程的切换,也降低了效率;于是就出现了DAM(Direct Memory Access),DMA最明显的一个特点是它不是用软件而是采用一个专门的控制器来控制内存与外设之间的数据交流,无须CPU介入,大大提高CPU的工作效率。在进行DMA数据传送之前,DMA控制器会向CPU申请总线控制权,CPU如果允许,则将控制权交出,因此,在数据交换时,总线控制权由DMA控制器掌握,在传输结束后,DMA控制器将总线控制权交还给CPU。

所以我们有多种实现异步的方式:利用多线程;IOCP 等,而IOCP就是使用了硬件的功能,虽然我们多起了一个线程,但是线程那I/O请求交给硬件驱动后就空闲了,回到线程池被其他调用。比如读取文件使用异步处理,需要把流修改为异步,并且调用Read的异步方法,这时候,线程把请求交给I/O就被回收了,流返回后在使用一个线程进行处理;如果只调用 Read异步方法,而流不支持异步,实际上是在内部用一个线程模拟了所谓的异步;最后就是流使支持异步,但使用同步的read方法,这个时候线程采用轮询的方法,等待操作完成。

继续阅读

0