C#線程池的代碼
sealed class MyThreadPool
{
//線程鎖對象
private static object lockObj = new object();
//任務隊列
private static Queue<ThreadStart> threadStartQueue = new Queue<ThreadStart>();
//記錄當前工作的任務集合,從中可以判斷當前工作線程使用數,如果使用int判斷的話可能會有問題,
//用集合的話還能取得對象的引用,比較好
private static HashSet<ThreadStart> threadsWorker = new HashSet<ThreadStart>();
//當前允許最大工作線程數
private static int maxThreadWorkerCount = 1;
//當前允許最小工作線程數
private static int minThreadWorkerCount = 0;
/// <summary>
/// 設定最大工作線程數
/// </summary>
/// <param name="maxThreadCount">數量</param>
public static void SetMaxWorkThreadCount(int maxThreadCount)
{
maxThreadWorkerCount = minThreadWorkerCount > maxThreadCount ?
minThreadWorkerCount : maxThreadCount;
}
/// <summary>
/// 設定最小工作線程數
/// </summary>
/// <param name="maxThreadCount">數量</param>
public static void SetMinWorkThreadCount(int minThreadCount)
{
minThreadWorkerCount = minThreadCount > maxThreadWorkerCount ?
maxThreadWorkerCount : minThreadCount;
}
/// <summary>
/// 啟動線程池工作
/// </summary>
/// <param name="threadStartArray">任務數組</param>
public static void MyQueueUserWorkItem(List<ThreadStart> threadStartArray)
{
//將任務集合都放入到線程池中
AddAllThreadsToPool(threadStartArray);
//線程池執行任務
ExcuteTask();
}
/// <summary>
/// 將單一任務加入隊列中
/// </summary>
/// <param name="ts">單一任務對象</param>
private static void AddThreadToQueue(ThreadStart ts)
{
lock (lockObj)
{
threadStartQueue.Enqueue(ts);
}
}
/// <summary>
/// 將多個任務加入到線程池的任務隊列中
/// </summary>
/// <param name="threadStartArray">多個任務</param>
private static void AddAllThreadsToPool(List<ThreadStart> threadStartArray)
{
foreach (var threadStart in threadStartArray)
AddThreadToQueue(threadStart);
}
/// <summary>
/// 執行任務,判斷隊列中的任務數量是否大于0,如果是則判斷當前正在使用的工作線程的
/// 數量是否大于等于允許的最大工作線程數,如果一旦有線程空閑的話
/// 就會執行ExcuteTaskInQueen方法處理任務
/// </summary>
private static void ExcuteTask()
{
while (threadStartQueue.Count > 0)
{
Thread.Sleep(100);
if (threadsWorker.Count < maxThreadWorkerCount)
{
ExcuteTaskInQueen();
}
}
}
/// <summary>
/// 執行出對列的任務,加鎖保護
/// </summary>
private static void ExcuteTaskInQueen()
{
lock (lockObj)
{
ExcuteTaskByThread(
threadStartQueue.Dequeue());
}
}
/// <summary>
/// 實現細節,這里使用BackGroudWork來實現后臺線程
/// 注冊doWork和Completed事件,當執行一個任務前,前將任務加入到
/// 工作任務集合(表示工作線程少了一個空閑),一旦RunWorkerCompleted事件被觸發則將任務從工作
/// 任務集合中移除(表示工作線程也空閑了一個)
/// </summary>
/// <param name="threadStart"></param>
private static void ExcuteTaskByThread(ThreadStart threadStart)
{
threadsWorker.Add(threadStart);
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (o, e) => { threadStart.Invoke(); };
worker.RunWorkerCompleted += (o, e) => { threadsWorker.Remove(threadStart); };
worker.RunWorkerAsync();
}
}
本文由用戶 cymt 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!