首選機制是推遲對象的創(chuàng)建,直到以后在 STA 線程下執(zhí)行代碼.
推薦的做法是在需要時或者在 Page_Load 方法中構造任何 COM 組件和外部資源。永遠不要將任何 STA COM 組件存儲在可以由構造它的線程以外的其他線程訪問的共享資源里。這類資源包括像緩存和會話狀態(tài)這樣的資源。即使 STA 線程調用 STA COM 組件,也只有構造此 STA COM 組件的線程能夠實際為該調用服務,而這要求封送處理對創(chuàng)建者線程的調用。此封送處理可能產生重大的性能損失和可伸縮性問題。在這種情況下,請研究一下使 COM 組件成為 MTA COM 組件的可能性,或者更好的辦法是遷移代碼以使對象成為托管對象。
將調用密集型的 COM 組件遷移到托管代碼
.NET Framework 提供了一個簡單的方法與傳統(tǒng)的 COM 組件進行交互。其優(yōu)點是可以在保留現有投資的同時利用新的平臺。但是在某些情況下,保留舊組件的性能開銷使得將組件遷移到托管代碼是值得的。每一情況都是不一樣的,決定是否需要遷移組件的最好方法是對 Web 站點運行性能測量。建議您研究一下如何將需要大量調用以進行交互的任何COM 組件遷移到托管代碼。許多情況下不可能將舊式組件遷移到托管代碼,特別是在最初遷移 Web 應用程序時。在這種情況下,最大的性能障礙之一是將數據從非托管環(huán)境封送到托管環(huán)境。因此,在交互操作中,請在任何一端執(zhí)行盡可能多的任務,然后進行一個大調用而不是一系列小調用。例如,公共語言運行庫中的所有字符串都是 Unicode 的,所以應在調用托管代碼之前將組件中的所有字符串轉換成 Unicode 格式。另外,一處理完任何 COM 對象或本機資源就釋放它們。這樣,其他請求就能夠使用它們,并且最大限度地減少了因稍后請求垃圾回收器釋放它們所引起的性能問題。
在 Visual Basic .NET 或 JScript. 代碼中使用早期綁定
以往,開發(fā)人員喜歡使用 Visual Basic、VBScript. 和 JScript. 的原因之一就是它們所謂“無類型”的性質。變量不需要顯式類型聲明,并能夠簡單地通過使用來創(chuàng)建它們。當從一個類型到另一個類型進行分配時,轉換將自動執(zhí)行。不過,這種便利會大大損害應用程序的性能。Visual Basic 現在通過使用 Option Strict 編譯器指令來支持類型安全編程。為了向后兼容,默認情況下,ASP.NET 不啟用該選項。但是,為了得到最佳性能,強烈建議在頁中啟用該選項。若要啟用 Option Strict,請將 Strict 屬性包括在 @ Page 指令中,或者,對于用戶控件,請將該屬性包括在 @ Control 指令中。下面的示例演示了如何設置該屬性,并進行了四個變量調用以顯示使用該屬性是如何導致編譯器錯誤的。
JScript. .NET 也支持無類型編程,但它不提供強制早期綁定的編譯器指令。若發(fā)生下面任何一種情況,則變量是晚期綁定的:被顯式聲明為 Object,是無類型聲明的類的字段,是無顯式類型聲明的專用函數或方法成員,并且無法從其使用推斷出類型。 最后一個差別比較復雜,因為如果 JScript. .NET 編譯器可以根據變量的使用情況推斷出類型,它就會進行優(yōu)化。在下面的示例中,變量 A 是早期綁定的,但變量 B 是晚期綁定的。
var A; var B; A = "Hello"; B = "World"; B = 0; 為了獲得最佳的性能,當聲明 JScript. .NET 變量時,請為其分配一個類型。例如,var A : String。
使請求管線內的所有模塊盡可能高效
請求管線內的所有模塊在每次請求中都有機會被運行。因此,當請求進入和離開模塊時快速地觸發(fā)代碼至關重要,特別是在不使用模塊功能的代碼路徑里。分別在使用及不使用模塊和配置文件時執(zhí)行吞吐量測試,對確定這些方法的執(zhí)行速度非常有用。
使用 HttpServerUtility.Transfer 方法在同一應用程序的頁面間重定向
采用 Server.Transfer 語法,在頁面中使用該方法可避免不必要的客戶端重定向。
必要時調整應用程序每個輔助進程的線程數
ASP.NET 的請求結構試圖在執(zhí)行請求的線程數和可用資源之間達到一種平衡。已知一個使用足夠 CPU 功率的應用程序,該結構將根據可用于請求的 CPU 功率,來決定允許同時執(zhí)行的請求數。這項技術稱作線程門控。但是在某些條件下,線程門控算法不是很有效。通過使用與 ASP.NET Applications 性能對象關聯的 Pipeline Instance Count 性能計數器,可以在 PerfMon 中監(jiān)視線程門控。當頁面調用外部資源,如數據庫訪問或 XML Web services 請求時,頁面請求通常停止并釋放 CPU。如果某個請求正在等待被處理,并且線程池中有一個線程是自由的,那么這個正在等待的請求將開始被處理。遺憾的是,有時這可能導致 Web 服務器上存在大量同時處理的請求和許多正在等待的線程,而它們對服務器性能有不利影響。通常,如果門控因子是外部資源的響應時間,則讓過多請求等待資源,對 Web 服務器的吞吐量并無幫助。為緩和這種情況,可以通過更改 Machine.config 配置文件節(jié)點的 maxWorkerThreads 和 maxIOThreads 屬性,手動設置進程中的線程數限制。
注意:輔助線程是用來處理 ASP.NET 請求的,而 IO 線程則是用于為來自文件、數據庫或 XML Web services 的數據提供服務的。分配給這些屬性的值是進程中每個 CPU 每類線程的最大數目。對于雙處理器計算機,最大數是設置值的兩倍。對于四處理器計算機,最大值是設置值的四倍。無論如何,對于有四個或八個 CPU 的計算機,最好更改默認值。對于有一個或兩個處理器的計算機,默認值就可以,但對于有更多處理器的計算機的性能,進程中有一百或兩百個線程則弊大于利。注意進程中有太多線程往往會降低服務器的速度,因為額外的上下文交換導致操作系統(tǒng)將 CPU 周期花在維護線程而不是處理請求上。
【 1 】 【 2 】 【 3 】 【 4 】 【 5 】 |