一、Asp.net中的線程池設置 在Asp.net的服務處理中,每當伺服器收到一個請求,HttpRuntime將從HttpApplication池中獲取一個HttpApplication對象處理此請求,請求的處理過程將被排入線程池中,對於Asp.net來說,在Machine.config文件的pr....
一、Asp.net中的線程池設置
在Asp.net的服務處理中,每當伺服器收到一個請求,HttpRuntime將從HttpApplication池中獲取一個HttpApplication對象處理此請求,請求的處理過程將被排入線程池中,對於Asp.net來說,在Machine.config文件的processModel部分中可以設置線程池中的參數。
Asp.net線程相關的參數配置:
參數 | 配置 |
autoConfig | 基於伺服器的配置自動設置。 |
maxWorkerThreads | 設置每個CPU的最大工作線程數量,可以設置為5~100,預設為20,建設設置為100 |
minWorkerThreads | 設置每個CPU的最少工作線程數量,預設為1 |
maxIoThreads | 配置每個CPU的最大I/O線程數量,可以設置的範圍為5~100,預設為20,建議設置為100 |
minIoThreads | 配置每個CPU最少工作線程數量,預設為1 |
HttpRuntime元素的配置參數:
參數 | 配置 |
minFreeThreads | 處理新請求保留的最少自由線程數量,預設值為8.建議每CPU設置為88個。這些最小空閑線程用於避免沒有線程可用而造成死鎖。因此,當線程池的線程小於這個數,請求就被排入隊列,而不會使用這些線程處理。 |
minLocalRequestFreeThreads | 為本地主機請求保留的最少自由線程數量,預設值為4.建議每CPU設置為76個。同上(只是針對本地請求) |
appRequestQueueLimit | 在Aso,net沒有足夠的線程來處理請求的時候,將會把這些請求排入一個請求隊列中等待處理,該項用來設置這個隊列的長度,當隊列長度超過這個參數將返回503、預設為5000。 |
優化的第一原則是:對於每一個請求儘可能使用一個線程完成處理。
二、非同步步驟中的非同步點
在HttpApplication的處理過程中,為了提高線程的利用率,對於一個請求儘可能只使用一個線程完成處理。
由於Asp.net處理採用管道的處理模式,必須保證處理步驟的邏輯順序。所以,有些處理必須在後繼的處理之前完成,所以,除非此時真的需要多個可以並行的計算密集任務,否則,啟動多個線程並不能提高網站的處理速度。
對於HttpApplication處理管道中每一個事件的處理步驟,有同步與非同步兩個方式處理:
- 同步:提供一個事件處理方法直接完成處理步驟;
- 非同步:一個用於啟動涉及I/O的處理步驟,一個用於I/O完成之後的處理步驟;
對於一個需要等待的處理步驟,我們可以分出一個非同步點,在這個非同步點之前啟動耗時的操作,然後直接結束當前的線程,在沒有線程參與的情況下,進行這個耗時的輸入輸出任務,在任務完成之後,重新從線程池獲取一個線程來繼續當前請求的處理。
如同步的BeginRequest對應的非同步處理方式定義如下:
public void AddOnBeginRequestAsync(BeginEventHandler bh, EndEventHandler eh)
其中BeginEventHandler用於啟動處理的委托,EndEventHandler用於處理完成任務之後的委托。
對於HttpApplication管道的處理來說,這些事件使用的同步方式的委托類型都是EventHandler類型,這個委托類型的定義如下:
public delegate void EventHandler(Object sender, EventArgs e)
對於非同步方式的處理,則使用相應的兩個委托完成,一個用於啟動的委托BeginEventHandler,一個用於結束的委托EndEventHandler。結束操作的委托將工作在一個線程池提供的線程之上。
在非同步方式下,處理管道將不再連續使用一個線程完成,而是每個處理步驟都可能在一個線程上進行,所以,我們不能假定處理管道總是處於一個線程,而使用基於線程的特征。