首页 新闻 赞助 找找看

使用线程池分配的多线程如何管理?

1
悬赏园豆:50 [已解决问题] 解决于 2010-12-16 15:28

我想做一个多线程下载的程序,具体需求是:

有成千上百的文件需要下载,由于每个文件较小,小于2M,所有我想采用每个线程下载一个文件的做法。

但是当我使用线程池把这些任务分配出去后,若用户要点击停止按钮停止下载,或者之后再继续下载,我就不知道该怎么做了。

所以我目前只有直接退出程序这么个笨办法。——因为不知道如何停止和继续线程。

 

还望高人指点。谢谢。

chzhcpu的主页 chzhcpu | 初学一级 | 园豆:120
提问于:2010-12-02 10:57
< >
分享
最佳答案
0

用 backgroudworker可以满足你的要求,特别是用于暂停和重启这个功能的时候

可参考codeproject上的demo: http://www.codeproject.com/KB/aspnet/ZetaWebSpider.aspx

收获园豆:10
蔡春升 | 初学一级 |园豆:3 | 2010-12-03 09:28
其他回答(5)
0

思维上可以不关注线程 关注任务。线程已经由线程池帮你管理好了

收获园豆:7
GUO Xingwang | 园豆:3885 (老鸟四级) | 2010-12-02 12:23
0

   个人认为如果要做到楼主所说的功能 自己弄一个线程 借助线程池只能对其完成情况进行处理 对过程无法干涉·

收获园豆:7
Fry_CiCi | 园豆:0 (初学一级) | 2010-12-02 12:34
0

为你的工作创建一个DownloadWorker类,为其添加 ManualResetEvent 成员变量, 通过ManualResetEvent控制任务运行,暂停,还是退出.

收获园豆:7
Launcher | 园豆:45045 (高人七级) | 2010-12-02 12:47
DownloadWorker应该要继承自thread类吧。
支持(0) 反对(0) chzhcpu | 园豆:120 (初学一级) | 2010-12-02 13:50
那我就要自己管理那些ownloadWorker s 了吧。 是不是放出去太多就会耗尽资源呢? 可是又如何管理呢?
支持(0) 反对(0) chzhcpu | 园豆:120 (初学一级) | 2010-12-02 13:54
0

写的一个demo,没仔细测,应该不会有错,希望对你有帮助

代码
using System;
using System.Security.Principal;
using System.Threading;
using System.Collections;
using System.Collections.Generic;

class ADPrincipal
{
static void Main(string[] args)
{
string[] filePah = new string[20];
for(int i=0;i<20;i++)
{
filePah[i]
=i+"";
}
DownloadManager manager
= new DownloadManager(filePah,5);
string cmd;
while((cmd=Console.ReadLine())!="end")
{
switch (cmd)
{
case "pause":
{
manager.Pause();
break;
}
case "start":
{
manager.Start();
break;
}
case "restart":
{
manager.Restart();
break;
}
case "stop":
{
manager.Stop();
break;
}
case "disposable":
{
manager.Dispose();
break;
}
}
}
}
}

/// <summary>
/// 管理类
/// </summary>
public class DownloadManager:IDisposable
{
private List<string> fileList;
private List<DownloadWork> workList;
private E_State state;
private int perPath;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="filePaths">下载的所有路径</param>
/// <param name="perPath">每个线程需要执行的路径数量</param>
public DownloadManager(string[] filePaths,int perPath)
{
this.state = E_State.Stop;
this.fileList = new List<string>(filePaths.Length);
foreach (string path in filePaths)
{
this.fileList.Add(path);
}
this.perPath = perPath;
}

/// <summary>
/// 执行下载
/// </summary>
/// <param name="perPath">表示每个线程处理几个路径</param>
private void Execute(int perPath)
{
this.state = E_State.Download;
int threadCount = this.fileList.Count % perPath == 0 ? this.fileList.Count / perPath : this.fileList.Count / perPath + 1;
workList
= new List<DownloadWork>(7);
DownloadWork work;
Thread thread;
List
<string> pathList = new List<string>(perPath);
int j=1,i=1;
foreach(string path in this.fileList)
{
pathList.Add(path);
if (i == j * perPath || i == this.fileList.Count)
{
work
= new DownloadWork(pathList.ToArray());
thread
= new Thread(new ThreadStart(work.Execute));
work.CurrentThread
= thread;
workList.Add(work);
pathList.Clear();
j
++;

thread.Start();
}
i
++;
}
}


/// <summary>
/// 开始下载
/// </summary>
public void Start()
{
if (this.state != E_State.Stop||this.fileList.Count==0)
{
throw new Exception("已经开始下载或没有路径");
}

this.Execute(this.perPath);
}

/// <summary>
/// 继续下载
/// </summary>
public void Restart()
{
if (this.state != E_State.Pause)
{
throw new Exception("没有暂停下载");
}

this.Execute(this.perPath);
}

/// <summary>
/// 停止整个下载过程
/// </summary>
public void Stop()
{
this.state = E_State.Stop;
foreach (DownloadWork work in workList)
{
work.Abort();
}
this.fileList.Clear();
this.workList.Clear();
}

private void RemovePath(List<string> doneList)
{
foreach (string path in doneList)
{
this.fileList.Remove(path);
}
}

/// <summary>
/// 暂停下载过程
/// </summary>
public void Pause()
{
this.state = E_State.Pause;
foreach (DownloadWork work in this.workList)
{
work.Abort();
//删除已经下载过的路径
this.RemovePath(work.DonePaths);
}
workList.Clear();
}

#region IDisposable 成员

public void Dispose()
{
this.Stop();
}

#endregion

enum E_State
{
Stop,
Download,
Pause
}
}


/// <summary>
/// 执行类
/// </summary>
public class DownloadWork
{
private string[] paths;
public List<string> DonePaths;
private Thread currentThread;
public Thread CurrentThread
{
set
{
this.currentThread = value;
}
}

public DownloadWork(string[] paths)
{
this.paths = paths;
this.DonePaths = new List<string>(paths.Length);
}

public void Execute()
{
//测试用
Thread.Sleep(1000 * 5);
foreach (string path in this.paths)
{
//根据路径来下载,这里用输出代替
Console.WriteLine(path);

//更新已下载
DonePaths.Add(path);

//测试用
Thread.Sleep(1000);
}
}

/// <summary>
/// 终止线程
/// </summary>
public void Abort()
{
try
{
if (this.currentThread.ThreadState != ThreadState.Stopped)
{
this.currentThread.Abort();
}
}
catch
{
}
}
}

 

 

收获园豆:18
wgz | 园豆:1254 (小虾三级) | 2010-12-02 16:26
0

mark

收获园豆:1
yearN | 园豆:551 (小虾三级) | 2010-12-05 21:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册