动态多线程任务管理

本来我的打算是做一个基于WebRequest的网络资源的下载程序的,后来发现单线程有的时候比较慢,于是就打算仿照Flashget做一个多线程下载的程序。

最开始我的设计是:首先获取文件的大小,根据大小创建该文件,然后将文件分为若干等分,每个线程下载一等份,所有线程共享一个文件流,每下载一部分就往文件里面写入一部分。

这个思路本身没有什么问题,在一些理想的情况下也能很好的工作。然而,把这个程序放到internat上时就没有那么理想了,并不是每个线程都能完整的完成该线程的任务的:有的线程只下载了一部分就不下载了,有的线程就根本无法开始下载(可能是由于服务器端限制了连接数)。一旦有一个线程无法完成下载任务,整个下载过程就失败了。

为了改正这个问题,就要实现动态多线程任务管理,使得只要有一个线程在工作,就能完成任务,并且可以随时添加,停止任务线程。该任务管理机制具有如下特点:

  1. 每个线程可以随时添加进来,并自动寻找合适的任务执行。
  2. 每个线程完成任务后会自动寻找下一个任务继续执行。
  3. 每个线程可以随时终止,未完成的任务会自动分配给其它执行线程。
  4. 只要有一个线程在运行,就能完成该任务。

要实现这种任务管理机制,就需要一种任务调度策略,这里我采用的方式是:

任务管理器维持三个队列:待完成的任务队列,运行中的任务队列,已完成的任务队列。在任何一个时候,这三个队列的合集就是总任务。

当有任务执行线程新任务需求时,按照下列策略分配:

  1. 如果待完成任务队列中有任务,则分配待完成的任务中最大的任务。
  2. 如果运行中的任务队列中有任务,则选取其中最大的任务分割,分配分割出来的任务。
  3. 如果上述条件均不满足,则无新任务分配。

当某个任务执行线程终止时,它剩余的任务将被放置到待完成任务队列中,以供其它线程执行。

根据以上需求,我做了一个demo,基本满足上述条件,截图如下:

在这个demo中,可以通过右边的复选框随时启动或者终止某个执行线程,每个线程的执行情况可以从图中的着色情况看出。

注:图中每个任务表示的方式如下[50,65)15,这是一个左闭右开的任务区间,表明任务起始点是50(包含50),终止点是65(不包含65),长度是15 。

本程序是用在.net 3.5环境下开发的,低版本的.netk框架可能无法运行。感兴趣的朋友可以下载玩一下。点击下载

由于这只是一个demo,还存在许多不完善的地方,代码又没有整理,比较乱。这里就不放代码了,如果有时间我会继续完善一下的。

原文地址:https://www.cnblogs.com/TianFang/p/863242.html