Thread.Sleep的主要功能是讓線程掛起一段時間,而指定的時候可以是毫秒為單位,由於windows操作並不是實時操作系統,所以當Thread.Sleep指定的毫秒數少於15以下那基本是不太可能在這個時間內恢復線程到工作狀態。既然是這樣那在設計隊列的時候就不得不面對一個處理延時的問題,首先看下以下代碼:
public virtual void Run()
{
while (!mDispose)
{
OnRun();
}
}
protected virtual void OnRun()
{
item = GetItem();
if (item != null)
{
try
{
using (item)
{
item.Execute();
}
}
catch { }
}
else
System.Threading.Thread.Sleep(SleepMS);
}
以上是一個簡單的隊列實現,當前隊列不存在工作的時候把當前線程Sleep一段時間,當隊列線程進行掛起后的時候有消息剛好進來,那這個消息不得不在15ms后才能被處理。也許這個延時只是很小完全可以接受,看一下以一個程序的實現。

以上是一個簡單的數據接收,邏輯處理和發送的調度過程。其環節存在着兩個隊列調度處理時,按上面所提到的情況來看這個處理的過程很有可能出現在處理上存在着幾十毫秒的延時,而這個延時的出現並不是處理資源不足導致,而是資源過剩所產生的結果。為什么這樣說呢,因為只有隊列空閑的情況下隊列線程才存在掛起的情況……
其實當隊列處於滿負載的情況線程掛起操作是不可能存在的,那如何去解決以上問題呢,其實可以使用Sleep(0)不讓線程掛指定時間,直接告訴操作系統把位置讓出來后馬上進入排隊,這樣可以保證處理延時縮到最短,當然也可以SpinWait。不過以上兩種解決方式都是比較搶占系統資源,當你的系統資源不充足的情況那還是不要采用。
實際情況可以采用緩解的手段來處理以上問題,把兩個隊列的工作合並到一起,這樣做的好處就是導致延時的環節少了,還有就是處理的東西壓縮在一個線程上這樣線程處於空閑的時間就更少。為了達到以上效果所以調度器和工作項設計就必須有一個規則約束,可以這樣實現一個調度器
public interface IDespatchItem : IDisposable
{
void Execute();
}
class Despatch : IDisposable
{
public Despatch()
{
System.Threading.ThreadPool.QueueUserWorkItem((o) => { Run(); });
}
public int SleepMS
{
get;
set;
}
private Queue<IDespatchItem> mQueues = new Queue<IDespatchItem>(1024);
public void Add(IDespatchItem item)
{
lock (mQueues)
{
if (item == null)
return;
mQueues.Enqueue(item);
}
}
public int Count
{
get
{
return mQueues.Count;
}
}
protected IDespatchItem GetItem()
{
lock (mQueues)
{
if (mQueues.Count > 0)
return mQueues.Dequeue();
return null;
}
}
protected virtual void OnRun()
{
IDespatchItem item = GetItem();
if (item != null)
{
try
{
using (item)
{
item.Execute();
}
}
catch { }
}
else
System.Threading.Thread.Sleep(SleepMS);
}
public virtual void Run()
{
while (!mDispose)
{
OnRun();
}
}
private bool mDispose = false;
public void Dispose()
{
lock (this)
{
if (!mDispose)
{
while (mQueues.Count > 0)
{
mQueues.Dequeue().Dispose();
}
mDispose = true;
}
}
}
}

