1)首先实现一个多线程的辅助类,代码如下:
public class ThreadMulti { public delegate void DelegateComplete(); public delegate void DelegateWork(int taskindex,int threadindex); public DelegateComplete CompleteEvent; public DelegateWork WorkMethod; private ManualResetEvent[] _resets; private int _taskCount = 0; private int _threadCount = 5; public ThreadMulti(int taskcount) { _taskCount = taskcount; } public ThreadMulti(int taskcount, int threadCount) { _taskCount = taskcount; _threadCount = threadCount; } public void Start() { if (_taskCount < _threadCount) { //任务数小于线程数的 _resets = new ManualResetEvent[_taskCount]; for (int j = 0; j < _taskCount; j++) { _resets[j] = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback(Work), new object[] { j, j }); } } else { _resets = new ManualResetEvent[_threadCount]; //任务数大于线程数 先把线程数的任务启动 for (int i = 0; i < _threadCount; i++) { _resets[i] = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback(Work), new object[] { i, i }); } //完成一个任务后在利用完成的那个线程执行下一个任务 int receivereset = 0; receivereset = ManualResetEvent.WaitAny(_resets); for (int l = _threadCount; l < _taskCount; l++) { _resets[receivereset].Reset(); ThreadPool.QueueUserWorkItem(new WaitCallback(Work), new object[] { l, receivereset }); receivereset = ManualResetEvent.WaitAny(_resets); } } ManualResetEvent.WaitAll(_resets); if (CompleteEvent != null) { CompleteEvent(); } } public void Work(object arg) { int taskindex = int.Parse(((object[])arg)[0].ToString()); int resetindex = int.Parse(((object[])arg)[1].ToString()); if (WorkMethod != null) { WorkMethod(taskindex + 1, resetindex+1); } _resets[resetindex].Set(); } }
ThreadMulti类能够根据根据传入的任务数和线程数,实现多线程的重复利用并执行指定的WorkMethod.
并且在任务完成后能触发CompleteEvent事件.
类中关键的是ManualResetEvent类的应用,能够在一个任务完成时通知程序哪个线程执行完毕,然后就安排另一个任务开始执行.
2)辅助类的应用应该挺简单吧
//实例化多线程辅助类并启动 ThreadMulti thread = new ThreadMulti(workcount); thread.WorkMethod = new ThreadMulti.DelegateWork(DoWork);//执行任务的函数 thread.CompleteEvent = new ThreadMulti.DelegateComplete(WorkComplete);//所有任务执行完毕的事件 thread.Start();
只需要指定任务数和执行任务的函数和完成任务后的事件即可.调用Start方法后,DoWork会在线程中调用并传递任务的index和执行线程的index.
public void DoWork(int index,int threadindex) { }
我们可以根据传进来的index来操作相应的数据,比如我们要导入一个大数据量的表到数据库中,我们可以根据分页函数把整个表分成若干个页,也就相当于我们程序中的任务,根据pageindex来到数据库中加载指定的页的数据然后对数据操作整理后可以插入到指定的表中.
在DoWork中当然可以显示执行的进度信息等等.
示例
截图
下载
/Files/zrx401558287/ThreadMultiPro.rar
听取了大家的意见做了一个修改版,确实比以前的专业了很多,尤其感谢老羽的宝贵意见,让我又长了见识了 呵呵
下面是新的修改版,希望大家多提建议啊
/Files/zrx401558287/ThreadMultiProNew.rar
完成了停止的功能,并且根据Hawker的建议精简了start方法,下面是更新的程序,大家看看怎么样:)
/Files/zrx401558287/ThreadMultiPro09081418.rar