摘要
最近項目中要做一個大資料量的操作,耗時很長,所以要用多線程來提高程式的執行速度.
因此寫了一個多線程的輔助類,能夠實現設定多線程的個數,然後就能重複利用這幾個線程執行分配的任務.
可以說是一個多線程的簡單應用,沒什麼高深的技術,希望園子的大牛多多指點:)
實現過程
1)首先實現一個多線程的輔助類,代碼如下:
Code
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