c#線程池的設計對於多線程程序來說相當重要,而系統自帶的線程池ThreadPool有很多缺陷,包括無法暫停和停止等。基於這個原因,筆者自行設計了幾款線程池,今天先發布的是基於信號量Semaphore的線程池設計。優點是:結構清晰、代碼簡潔。缺點是:由於需要有用戶模式切換到內核模式,效率較低。
這裡就不給出信號量的基本編程原理了,直接上代碼^_^
using System;
using System.Threading;
/**************************************************************
* Thread Manager 類
* Author:freemouse
* E-mail:[email protected]
* ***********************************************************/
namespace Freemouse.Base.ThreadManage
{
/// <summary>
/// 基於信號量的多線程管理器
/// </summary>
public class ThreadManager : SemaphoreThreadPool, iThreadManager
{
/// <summary>
/// 控制啟動、停止
/// </summary>
private ManualResetEvent m_event;
private int m_iThreadNum;
private bool bPause;
private bool bStoped;
private bool bStart;
/// <summary>
/// 標記線程管理器運作
/// </summary>
public bool Running
{
get { return bStart && !bPause && !bStoped; }
}
public ThreadManager(int threadNum):base(0,threadNum,null)
{
m_iThreadNum = threadNum;
ControlCallback = new ThreadControl(Run);
m_event = new ManualResetEvent(false);
bPause = false;
bStoped = false;
bStart = false;
}
public void Run()
{
while (bPause || bStoped || !bStart)
{
if (bStoped)
{
Thread.CurrentThread.Abort();
}
m_event.WaitOne();
Thread.Sleep(20);
}
Thread.Sleep(20);
}
public virtual void Start()
{
bPause = false;
bStoped = false;
bStart = true;
m_Pool.Release(m_iThreadNum);
m_event.Set();
}
public void Stop()
{
bStoped = true;
bStart = false;
bPause = false;
}
public void Pause()
{
bPause = true;
bStoped = false;
bStart = true;
m_event.Reset();
}
public void Resume()
{
bPause = false;
bStoped = false;
bStart = true;
m_event.Set();
}
}
public delegate void ThreadCallback(object obj);
public delegate void ThreadControl();
/// <summary>
/// 信號量線程池
/// </summary>
public class SemaphoreThreadPool
{
protected Semaphore m_Pool;
private bool m_bCreateNew;
public bool CreateNew
{
get { return m_bCreateNew; }
}
protected ThreadControl m_control;
public ThreadControl ControlCallback{
set{
m_control = value;
}
get{
return m_control;
}
}
public SemaphoreThreadPool(int initCount,int maxCount,string name)
{
m_Pool = new Semaphore(initCount,maxCount,name,out m_bCreateNew);
}
/// <summary>
/// 為工作任務新建一個線程
/// </summary>
/// <param name="callback">ThreadCallback</param>
/// <param name="obj">傳遞參數</param>
public void QueueWorkItem(ThreadCallback callback,object obj)
{
Thread thread = new Thread(delegate() {
if(m_control != null)
m_control();
threadRun(callback, obj);
});
thread.Start();
}
protected virtual void threadRun(ThreadCallback callback,object obj){
m_Pool.WaitOne();
callback(obj);
m_Pool.Release();
}
}
public interface iThreadManager
{
bool Running
{
get;
}
void Start();
void Stop();
void Pause();
void Resume();
void Run();
}
}