傳統同步阻塞模式下,每個請求佔用一線程,高併發時線程資源耗盡。本文介紹利用 ThreadPool.RegisterWaitForSingleObject 實現高效的「無線程等待」模式,構建可伸縮的 HTTP 服務端。
HttpListener 異步接收請求 (BeginGetContext),隨即委派耗時業務邏輯至線程池異步執行 (Delegate.BeginInvoke)。AsyncWaitHandle 註冊回調 (RegisterWaitForSingleObject),設定超時時間 (如 5000ms)。因 WaitOrTimerCallback 不支援 ref 參數,採用 Dictionary<int, string> 存儲請求結果。每個請求分配唯一序列號 (循環範圍 10,000~100,000),作為字典 Key,分別傳遞給業務處理委派與等待回調,實現無鎖高效讀寫 (字典預分配容量,避免擴容競爭)。
// 監聽回調
IAsyncResult ar = asyncHandlerDelegate.BeginInvoke(request, seq, null, null);
ThreadPool.RegisterWaitForSingleObject(
ar.AsyncWaitHandle,
RequestCompleteCallback,
new object[] { response, seq },
5000, true);
// 完成回調
void RequestCompleteCallback(object state, bool isTimeout) {
var arr = (object[])state;
var resp = (HttpListenerResponse)arr[0];
int key = (int)arr[1];
string result = isTimeout ? "504 time out" : dict[key];
// 輸出響應...
}
優勢:主線程無阻塞,線程池線程僅用於實際計算/IO,極大提升併發承載能力。
待驗證:大量等待句柄的性能開銷;HttpListener 自身的穩定性與性能上限。