明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

ASP 組件向?qū)?/h1>

[摘要]作者:J.D. MeierMicrosoft Corporation2000 年 1 月 24 日如果您符合以下幾種情況,這篇文章正適合您:從 Active Server Pages (ASP) 代...
作者:J.D. Meier
Microsoft Corporation

2000 年 1 月 24 日

如果您符合以下幾種情況,這篇文章正適合您:

從 Active Server Pages (ASP) 代碼調(diào)用組件
設(shè)計(jì)將從 ASP 代碼調(diào)用的組件
希望利用 ASP 代碼中的組件
目錄
簡(jiǎn)介
為什么使用組件?
狀態(tài)管理
范圍
分割服務(wù)
線程模型
安全性
Server.CreateObject 與 CreateObject
傳遞參數(shù)
事件
OnStartPage/OnEndPage 與 ObjectContext
錯(cuò)誤處理
全局變量
分布組件
結(jié)論

簡(jiǎn)介
組件。有人喜歡它們,有人則害怕。害怕組件的人通常都能給您講一個(gè)駭人的經(jīng)歷。讓我們面對(duì)它:當(dāng)開(kāi)始在 ASP 下使用組件時(shí),并不知道什么能傷害您。如果您摔倒了,那么站起來(lái),自己拍干凈,然后接著來(lái)。在這篇文章中,我將提供從實(shí)踐中獲得的一般指南,幫助您建立更好的基于組件的 ASP 解決方案。

為什么使用組件?
在我開(kāi)始討論組件指南之前,值得考慮將組件添加到 ASP 應(yīng)用程序的價(jià)值。許多對(duì)組件不熟悉的開(kāi)發(fā)人員總覺(jué)得一切都那么新鮮。組件可以為 ASP 應(yīng)用程序帶來(lái)以下種種益處:

封裝功能和隱藏實(shí)現(xiàn)細(xì)節(jié)
可重用性(包括被不同客戶機(jī)應(yīng)用程序重復(fù)使用)
知識(shí)產(chǎn)權(quán)保護(hù)
可伸縮性(體現(xiàn)在允許將應(yīng)用程序分布到多臺(tái)計(jì)算機(jī)上)
配置和部署靈活性
性能(尤其在早期綁定是重要因素時(shí))
訪問(wèn)系統(tǒng),例如 Win32 API 調(diào)用或編程語(yǔ)言的任何其他底層功能
鍵入功能較強(qiáng)(“Visual Basic® 腳本編輯器 [VBScript]”的鍵入功能較弱,而且 JScript® 也不太好)
業(yè)務(wù)邏輯與用戶界面分離,或者 Web 設(shè)計(jì)人員與 Web 開(kāi)發(fā)人員分離
利益與付出同在。就增加開(kāi)發(fā)過(guò)程的復(fù)雜性而論,創(chuàng)建組件解決方案可能更加昂貴。部署和疑難解答也可能變得更困難并成為現(xiàn)實(shí)因素。但是,不要讓眼前的困難阻礙了長(zhǎng)期的利益。如何知道付出的成本是否值得呢?請(qǐng)考慮下列方面:

現(xiàn)有的代碼庫(kù)是如何?
開(kāi)發(fā)隊(duì)伍的水平和經(jīng)驗(yàn)怎樣?
您對(duì)主服務(wù)器的控制范圍如何?
為特定任務(wù)選擇了什么樣的工具和語(yǔ)言?
存在什么協(xié)同問(wèn)題?
存在性能和可伸縮性的因素嗎?
項(xiàng)目時(shí)間框架是什么?
誰(shuí)會(huì)繼續(xù)維護(hù)和支持該應(yīng)用程序?例如,開(kāi)發(fā)小組能介入和接管嗎?
審查以上考慮的問(wèn)題后,請(qǐng)考察您的假設(shè)。原型能迅速?gòu)脑O(shè)想中得出實(shí)際情況。

現(xiàn)在,對(duì)組件可能帶來(lái)的益處有了一定的理解,讓我們繼續(xù)討論。下面的指南將幫助您獲得最大的益處。這些指南可能成為指引您順利建立更穩(wěn)定的、可升級(jí)的、性能更優(yōu)的 ASP 組件應(yīng)用程序的向?qū)А?br>
狀態(tài)管理
建議
一般來(lái)說(shuō),在可能的場(chǎng)合盡量使用無(wú)狀態(tài)的組件和無(wú)狀態(tài)的 ASP 頁(yè)面。組件不應(yīng)需要狀態(tài)從一個(gè)方法調(diào)用到下一個(gè)狀態(tài)。將復(fù)雜的狀態(tài)存儲(chǔ)在數(shù)據(jù)庫(kù)中。對(duì)于簡(jiǎn)單的數(shù)據(jù)、沿用 cookies、QueryString 或在頁(yè)面之間傳遞數(shù)據(jù)的隱藏的表單字段。

為什么
服務(wù)器資源是有限的。維護(hù)組件中的狀態(tài)意味著應(yīng)用程序在資源沖突和并發(fā)問(wèn)題時(shí)將消耗寶貴的資源。無(wú)狀態(tài)組件將幫助您避免這些問(wèn)題。無(wú)狀態(tài)組件還提供更多的部署選項(xiàng),并增強(qiáng)在多個(gè)客戶機(jī)上共享資源的能力。

常見(jiàn)的陷阱
開(kāi)發(fā)人員常犯的錯(cuò)誤是設(shè)計(jì)或使用需要維護(hù)狀態(tài)的組件。請(qǐng)注意防止這種常用于桌面開(kāi)發(fā)的思想。通常,具有桌面開(kāi)發(fā)背景的開(kāi)發(fā)人員會(huì)設(shè)計(jì)出依賴(lài)狀態(tài)的組件。

詳細(xì)信息
避免使用“ASP 會(huì)話”將提高服務(wù)器的性能,因?yàn)樗?jiǎn)化了代碼路徑并減少了服務(wù)器資源的消耗。如果不使用“ASP 會(huì)話”,請(qǐng)通過(guò)“Internet 服務(wù)管理器” (請(qǐng)參閱“Internet 信息服務(wù) [IIS]”文檔)禁用“會(huì)話”狀態(tài)。也可以在不需要“會(huì)話”的 ASP 頁(yè)面中使用下面的標(biāo)記禁用基于頁(yè)的“會(huì)話”:

<%@ENABLESESSIONSTATE=False %>
部署靈活性是另一個(gè)重要方面,尤其在 Web 區(qū)域中運(yùn)行應(yīng)用程序時(shí)。如果依賴(lài)“ASP 會(huì)話”, 則給定用戶的請(qǐng)求綁定在指定的 Web 服務(wù)器上,因?yàn)椤皶?huì)話”狀態(tài)是服務(wù)器專(zhuān)用的。在中間層和 Web 服務(wù)器中避免狀態(tài),并使用數(shù)據(jù)庫(kù),將使 ASP 請(qǐng)求可由區(qū)域中任何有效的 Web 服務(wù)器處理。因此, 您將減少競(jìng)爭(zhēng),提供更好的冗余,并允許更多的分布選項(xiàng)。

不使用“ASP 會(huì)話”而在頁(yè)間傳遞數(shù)據(jù)的其他方法,請(qǐng)參閱下面的“知識(shí)庫(kù) (KB)”文章:

Q175167 HOWTO: Persisting Values Without Sessions(英文)  
Q157906 HOWTO: Maintain State Across Pages with VBScript(英文)  
Don Box 在 ActiveX&reg; Q&A(英文) 一文中 還提出有關(guān) MTS 狀態(tài)管理的更多見(jiàn)解。

范圍
建議
通常,請(qǐng)?jiān)陧?yè)面范圍內(nèi)使用組件。頁(yè)面范圍的含義就是在同一頁(yè)上創(chuàng)建對(duì)象、并使用它和釋放它 — 所有這些均在同一頁(yè)上操作。

標(biāo)記為“雙重”或“單元”的組件在頁(yè)面范圍內(nèi)都能正常工作。僅在頁(yè)面范圍內(nèi)使用“單元”模型組件,例如 VisualBasic 組件。如果需要在“應(yīng)用程序”或“會(huì)話”中存儲(chǔ)組件,則建議使用“雙重”。可以在“會(huì)話”或“應(yīng)用程序”范圍內(nèi)存儲(chǔ)標(biāo)記為“雙重”的組件,但組件需要保證線程安全。

為什么
在頁(yè)面范圍內(nèi)使用組件使服務(wù)器資源得以回收。釋放資源將使并發(fā)問(wèn)題減到最小程度,并允許可匯集的資源在客戶機(jī)上共享。另外,頁(yè)面范圍組件避免了影響“會(huì)話” 或“應(yīng)用程序”范圍的對(duì)象的線程問(wèn)題。在下面的“線程模型分類(lèi)”中將詳細(xì)討論線程問(wèn)題。

常見(jiàn)的陷阱
最常見(jiàn)的問(wèn)題之一就是在“應(yīng)用程序”范圍內(nèi)存儲(chǔ) Visual Basic 或其他“單元”模型對(duì)象。如果您嘗試在“應(yīng)用程序”范圍內(nèi)存儲(chǔ)一個(gè)用 Server.CreateObject 創(chuàng)建的“單元”模型對(duì)象,可以看見(jiàn)下面的錯(cuò)誤:

應(yīng)用程序?qū)ο箦e(cuò)誤 'ASP 0197: 80004005'

不允許的對(duì)象使用

/VirDir/global.asa, line 7

不能將帶有單元模型行為的對(duì)象添加到應(yīng)用程序的內(nèi)部對(duì)象。

但是,如果使用 <OBJECT> 標(biāo)記在“應(yīng)用程序”范圍內(nèi)存儲(chǔ)“單元”模型對(duì)象,就不會(huì)出現(xiàn)運(yùn)行錯(cuò)誤。相反,對(duì)象將創(chuàng)建在指定的“單線程單元 (STA)”線程上,并且所有調(diào)用都匯集到那個(gè)線程 — 而且是連續(xù)地。原因是沒(méi)有復(fù)選該組件的線程模型。很遺憾,在運(yùn)行時(shí)出現(xiàn)了問(wèn)題。

另一個(gè)常見(jiàn)問(wèn)題是在“會(huì)話”范圍存儲(chǔ)“單元”模型對(duì)象,該“會(huì)話”范圍將用戶會(huì)話綁定到指定的線程。這個(gè)行為嚴(yán)重影響服務(wù)器的性能。由于所有調(diào)用將連續(xù)地匯集到創(chuàng)建該對(duì)象的線程,因此從根本上影響了線程緩沖池的目的。

詳細(xì)信息
有關(guān)詳細(xì)內(nèi)容,請(qǐng)參閱下面的 KB 文章:

Q243543 INFO: Do Not Store STA Objects in Session or Application(英文)  
Q243548 INFO: Design Guidelines for VB Components Under ASP(英文)  
分割服務(wù)
建議
將表達(dá)、業(yè)務(wù)和數(shù)據(jù)服務(wù)分離。業(yè)務(wù)組件應(yīng)該實(shí)施業(yè)務(wù)規(guī)則。業(yè)務(wù)組件不應(yīng)包含數(shù)據(jù)訪問(wèn)技術(shù)。那是數(shù)據(jù)層組件的任務(wù)。業(yè)務(wù)組件不應(yīng)包含對(duì) ASP 對(duì)象的引用。

ASP 提供表達(dá)服務(wù)。引用 ASP 的對(duì)象應(yīng)該呈現(xiàn)為 HTML。這些對(duì)象能夠依次調(diào)用對(duì) MTS/COM+ 注冊(cè)的業(yè)務(wù)對(duì)象。

為什么
將應(yīng)用程序分割為單獨(dú)的和截然不同的服務(wù),有以下好處:

更便于組件的重用
支持 Windows DNA model(英文)  
更好地孤立疑難問(wèn)題
更靈活的部署選項(xiàng)(去掉服務(wù)的耦合允許在多臺(tái)計(jì)算機(jī)上分布應(yīng)用程序)
常見(jiàn)的陷阱
有一種我們稱(chēng)為“瑞士軍刀”組件的常見(jiàn)問(wèn)題。 該“瑞士軍”組件將所有服務(wù)合成一體 (就像有螺絲錐、牙簽等 17 種工具的小瑞士軍刀)。 把不相關(guān)的服務(wù)組合到一個(gè)組件中, 使該組件很難使用、理解和維護(hù)。

容易掉入的另一個(gè)陷阱是從業(yè)務(wù)組件中引用 ASP。使 ASP 和業(yè)務(wù)邏輯耦合(通過(guò)使用 請(qǐng)求或響應(yīng)對(duì)象,或在其內(nèi)部構(gòu)建 HTML),不僅限制不同的客戶機(jī)重用您的組件,而且限制了橫向的可伸縮性。引用 ASP 內(nèi)置對(duì)象的對(duì)象應(yīng)該與 Web 服務(wù)器在同一框圍中。理想情況下,由于橫向可伸縮性,業(yè)務(wù)組件可以分布在不同的框圍中?梢灾苯釉 ASP 腳本中提供表達(dá)服務(wù),也可以建立呈現(xiàn)引用 ASP 內(nèi)置對(duì)象的組件的 HTML,并將這些組件保持在 IIS 框圍中。

詳細(xì)信息
成功的設(shè)計(jì)模型可用作處理公共業(yè)務(wù)問(wèn)題的模型。例如,處理“創(chuàng)建讀更新刪除(CRUD)” 操作的模型,可幫助您將應(yīng)用程序分為幾個(gè)截然不同的邏輯服務(wù),即表達(dá)、業(yè)務(wù)規(guī)則和數(shù)據(jù)訪問(wèn)。

請(qǐng)參閱下文以獲得更多的設(shè)計(jì)模型具體示例,可以在您自己的應(yīng)用程序中模仿它:

Scalable Design Patterns(英文)
Simplify MTS Apps with a Design Pattern(英文)
FMStocks Application: Start Here(英文)
線程模型
建議
選擇組件的范圍還是選擇組件的線程模型,哪種方法優(yōu)先??jī)煞N方法都要考慮線程分支,除非決定在頁(yè)面范圍內(nèi)使用“單元”或“雙重”模型組件。(如果 Visual Basic 程序員不知道組件是哪種線程模型,則總是“單元”。)

如果需要在“應(yīng)用程序”或“會(huì)話”中存儲(chǔ)對(duì)象,則需要使用標(biāo)記為“雙重”的組件并聚集“自由線程編組程序 (FTM)”。

不要使用“單線程”組件并避免使用來(lái)自 ASP 的“自由線程”組件。

注意: 如果不小心, Visual Basic 可產(chǎn)生“單線程”組件。請(qǐng)確保在項(xiàng)目屬性頁(yè)的常規(guī)選項(xiàng)卡上將線程模型設(shè)置為單元線程。還要注意在相同選項(xiàng)卡上選定無(wú)人值守執(zhí)行和保留在內(nèi)存中選項(xiàng)。

為什么
如果您使用的是 Visual Basic,它是一種“傻瓜”開(kāi)發(fā)環(huán)境。 Visual Basic 僅限于使用“單元”模型。假如 Visual Basic“單元”模型對(duì)象執(zhí)行得非常良好,我不想對(duì)頁(yè)面范圍上的限制考慮太多。 Fitch 和 Mathers Stock 2000 破壞了對(duì)性能的任何預(yù)先想法。另外,由 ASP、SQL 和 Visual Basic 構(gòu)建的許多現(xiàn)有網(wǎng)站,無(wú)時(shí)不刻都在證明頁(yè)面范圍的“單元”模型組件是可伸縮和執(zhí)行的。

如果在標(biāo)記為“雙重”的組件上聚集 FTM,則可以不用任何編組或線程切換,便能在線程之間調(diào)用。如果標(biāo)記為“雙重”的組件沒(méi)有聚集 FTM,ASP 將其視為“單元”線程對(duì)象 — 就像 Visual Basic 組件一樣。請(qǐng)記住,如果計(jì)劃利用“COM+ 對(duì)象池”,則不要聚集 FTM。 有關(guān)“對(duì)象池”的規(guī)則,請(qǐng)參閱“平臺(tái) SDK”文檔。

“單線程”和“自由線程”組件運(yùn)行在“系統(tǒng)”安全環(huán)境下。更糟的是,“單線程”組件會(huì)導(dǎo)致死鎖。

常見(jiàn)的陷阱
也許最常見(jiàn)的陷阱就是使用了沒(méi)有被設(shè)計(jì)為在 ASP 下運(yùn)行的組件,如“單線程”組件。大多數(shù)開(kāi)發(fā)人員陷入其中,是因?yàn)閷⒆烂鎽?yīng)用程序移向 ASP,或者使用了第三方的控件時(shí)。如果您不能確定組件的線程模型,可以檢查組件的注冊(cè)表項(xiàng)(但不能總依賴(lài)它)。

詳細(xì)信息
有關(guān)線程模型及其對(duì) ASP 的影響,請(qǐng)參閱下面的文章:

Don Box's Active Server Pages and COM Apartments(英文)  
Agility in Server Components
另外,下面的 KB 文章提供了有關(guān)線程問(wèn)題的詳細(xì)內(nèi)容:

Q243543 Single-Threaded Apartment Objects in Session or Application(英文)  
Q243544 INFO: Component Threading Model Summary Under Active Server Page(英文)  
Q150777 INFO: Descriptions and Workings of OLE Threading Models(英文)  
安全性
建議
組件不應(yīng)對(duì)它運(yùn)行的用戶環(huán)境做任何假設(shè)。不要訪問(wèn)用戶專(zhuān)用信息,如 HKEY_CURRENT_USER,或桌面計(jì)算機(jī)的專(zhuān)用資源,因?yàn)檫@些對(duì)組件來(lái)講是不可用的。應(yīng)用程序也不要使用 SendKeys 或調(diào)用依賴(lài)用戶界面的組件,執(zhí)行通常需要桌面交互的操作,如打開(kāi)對(duì)話框。

為什么
組件將運(yùn)行在不同安全性的桌面上。首先,這表示應(yīng)用程序不能打開(kāi)對(duì)話框,并不能與其他 GUI 實(shí)用程序交互(例如,使用 SendKeys)。默認(rèn)情況下,不允許 Inetinfo.exe 與桌面交互。不同的用戶環(huán)境也會(huì)限制組件訪問(wèn)某些資源 — 主要是注冊(cè)表的 HKEY_CURRENT_USER 部分。

常見(jiàn)的陷阱
常見(jiàn)的失誤是引用 HKEY_CURRENT_USER 下的表項(xiàng)。例如,Visual Basic 的 GetSetting 和 SaveSetting 函數(shù)不能在 ASP 下使用,因?yàn)樗鼈円昧?HKEY_CURRENT_USER 配置單元下的表項(xiàng)。下面的 KB 將討論這個(gè)問(wèn)題:

Q248348 PRB: SaveSetting and GetSetting Not Available in Visual Basic 6.0 Webclass (IIS Application)(英文)  
當(dāng)從 ASP 而不是從桌面客戶機(jī)調(diào)用組件時(shí),打印機(jī)、MAPI 信息和網(wǎng)絡(luò)共享通!笆А薄

有關(guān)詳細(xì)內(nèi)容,請(qǐng)參閱下面的 KB 文章:

Q184291 PRB: COM Objects Fail to Print When Called From ASP(英文)
Q217144 INFO: Difficulties Using Net APIs in ISAPI and ASP COM Objects(英文)  
Q207671 HOWTO: Accessing Network Files from IIS Applications(英文)  
詳細(xì)信息
有關(guān)安全性的幾點(diǎn)考慮:

啟用哪種 IIS 身份驗(yàn)證方法?
您的 Web 應(yīng)用程序是進(jìn)程內(nèi)的還是進(jìn)程外的?
如果組件以 MTS 或 COM+ 注冊(cè),它是在“服務(wù)器”上還是在庫(kù)軟件包中?
您正在調(diào)用本地 DLL、遠(yuǎn)程 DLL、本地 EXE、遠(yuǎn)程 EXE 嗎?
有關(guān)安全性的詳細(xì)說(shuō)明超出了本文的范圍。但是,由于這個(gè)主題的復(fù)雜性,下面的文章對(duì)從 ASP 組件角度理解問(wèn)題有很大幫助:

Securing a Web-based Microsoft Transaction Server Application(英文)
Q172925 INFO: Security Issues with Objects in ASP and ISAPI Extensions(英文)  
Q217202 PRB: CGI Applications and IIS OOP Applications May Fail(英文)  
下文很好地概述了 IIS 如何處理安全性:

Authentication and Security for Internet Developers(英文)
Server.CreateObject 與 CreateObject
建議
使用 Server.CreateObject。如果正在使用 MTS/COM+ 庫(kù)軟件包,請(qǐng)使用 Server.CreateObject 來(lái)避免線程阻塞。

為什么
CreateObject 相當(dāng)于通過(guò)腳本引擎調(diào)用 CoCreateInstance。如果使用 CreateObject 而不是 Server.CreateObject,將發(fā)生下面情況:

ASP 不能識(shí)別該對(duì)象。
OnStartPage/OnEndPage 頁(yè)面方法沒(méi)有調(diào)用。
ASP 不知道對(duì)象的線程模型。
Server.CreateObject 相當(dāng)于 GetObjectContext.CreateInstance。這表示 ASP 清楚該對(duì)象并知道它的線程模型。另外,如果 ASP 頁(yè)面是事務(wù)性的,則通過(guò)調(diào)用 Server.CreateObject 可使組件與 ASP 頁(yè)面在同一事務(wù)中。(請(qǐng)注意,事務(wù)性的頁(yè)面可能意味著可避免的業(yè)務(wù)規(guī)則與表達(dá)層的耦合。)

常見(jiàn)的陷阱
如果對(duì)象處于防火墻后面,可能需要調(diào)用 CreateObject。請(qǐng)參閱 Q193230 PRB: Server.CreateObject Fails when Object is Behind Firewall(英文)  以獲得詳細(xì)信息。

詳細(xì)信息
雖然在 IIS 4.0 下面 CreateObject比 Server.CreateObject 快,但在 IIS 5.0 下性能是相同的。同樣,如果正在使用 MTS/COM+ 庫(kù)軟件包/應(yīng)用程序, Server.CreateObject 可防止線程阻塞。

傳遞參數(shù)
建議
聲明 Out 參數(shù)為 Variant。在 Visual Basic 術(shù)語(yǔ)中,這表示按引用 參數(shù)應(yīng)該為 Variant。按值傳遞的參數(shù)(In 參數(shù))不限于 Variant,但必須與 Variant 兼容。

為什么
腳本客戶機(jī)使用 Variant。 COM 服務(wù)器可使用指定的數(shù)據(jù)類(lèi)型。當(dāng)您將指定的數(shù)據(jù)類(lèi)型按值傳遞給 COM 服務(wù)器時(shí), COM 服務(wù)器可以毫無(wú)問(wèn)題地接收。但除 Variant 外,其他按引用參數(shù)無(wú)法“回送”給 ASP 腳本。

常見(jiàn)的陷阱
最常見(jiàn)的錯(cuò)誤之一是“類(lèi)型不匹配”。這通常是因?yàn)榘匆?傳遞到 COM 對(duì)象的變量不是 Variant。通常的解決方法是按值傳遞參數(shù)或者將參數(shù)變?yōu)?Variant。

詳細(xì)信息
如果要在多臺(tái)計(jì)算機(jī)上分布組件或在進(jìn)程外運(yùn)行它們,可能看到按值 傳遞參數(shù)獲得的顯著性能。按引用傳遞將在進(jìn)程或計(jì)算機(jī)間造成更多的編組開(kāi)銷(xiāo),因?yàn)閿?shù)據(jù)必須往復(fù)發(fā)送。如果實(shí)際上并不需要按引用傳遞參數(shù)時(shí), 按值傳遞參數(shù)的正確性和有效性也是一個(gè)問(wèn)題。注意,在默認(rèn)情況下 Visual Basic 按引用傳遞參數(shù)。

下面的 KB 文章討論將參數(shù)從 ASP 傳遞到 COM 對(duì)象:

Q197956 PRB: Passing Parameters By Reference to a VB COM Object(英文)  
Q197957 PRB: Passing Parameters By Reference to a VC COM Object(英文)  
事件
建議
避免調(diào)用等待其他組件返回事件的組件。

組件方法應(yīng)盡快返回對(duì) ASP 的執(zhí)行。請(qǐng)考慮使用“MSMQ”或“COM+ 排隊(duì)組件” 來(lái)提供異步調(diào)用 — 或當(dāng)要做的工作正長(zhǎng)時(shí)間運(yùn)行并且不必聯(lián)機(jī)運(yùn)行時(shí)。

請(qǐng)異步地分派工作項(xiàng)目,而不要讓 ASP 等待長(zhǎng)時(shí)間運(yùn)行的進(jìn)程結(jié)束。然后您將從 ASP 給客戶機(jī)返回一個(gè)響應(yīng)。一旦工作項(xiàng)目完成,您可以用電子郵件或其他方法通知客戶機(jī)(請(qǐng)參閱下面內(nèi)容)。

為什么
ASP 并不是為處理事件設(shè)計(jì)的。為了優(yōu)化服務(wù)器性能,請(qǐng)盡快返回對(duì) HTTP 請(qǐng)求的響應(yīng)。

常見(jiàn)的陷阱
循環(huán)檢查服務(wù)器上的狀態(tài)標(biāo)識(shí)并不是一種提供瀏覽器通知的“服務(wù)器友好”方法。

詳細(xì)信息
通常開(kāi)發(fā)人員關(guān)注事件的原因是為了給瀏覽器提供關(guān)于在服務(wù)器上處理的工作的通知。雖然可以開(kāi)發(fā)出精致的瀏覽器通知系統(tǒng),如通過(guò)套接字在服務(wù)器上打開(kāi)另一個(gè)端口,但許多開(kāi)發(fā)人員通過(guò)下面的技術(shù)實(shí)現(xiàn)他們的需要:

使用電子郵件通知
在頁(yè)面中添加 Meta-Refresh 標(biāo)記以輪詢服務(wù)器。
發(fā)送到瀏覽器的連接,并讓客戶機(jī)手動(dòng)檢查未決請(qǐng)求的狀態(tài)。
下面的 KB 文章討論這些問(wèn)題:

Q243547 PRB: ASP Does Not Provide Progress Notifications to Client Browsers(英文)  
Q243546 PRB: ASP Does Not Support Events(英文)  
OnStartPage/OnEndPage 與 ObjectContext
建議
在 IIS 4.0 及更高版本中使用 ObjectContext 訪問(wèn) ASP 內(nèi)置對(duì)象(如響應(yīng)、請(qǐng)求、服務(wù)器等等)。無(wú)論何時(shí)請(qǐng)盡量避免使用 ScriptingContext 對(duì)象、 OnStartPage 和 OnEndPage。

為什么
OnStartPage、OnEndPage 和 ScriptingContext 對(duì)象是用于遺留支持的。

常見(jiàn)的陷阱
如果插入 ASP 對(duì)象,ATL 向?qū)⑹褂?OnStartPage 和 OnEndPage。

詳細(xì)信息
用“雙重”或“單元”模型組件獲取 ObjectContext 而無(wú)須以 MTS/COM+ 進(jìn)行注冊(cè)。對(duì)于本地的 ActiveX EXE 不能使用 ObjectContext,所以需要使用 OnStartPage/OnEndPage。若要使用“自由線程”和“單線程”組件環(huán)境,需要以 MTS/COM+ 注冊(cè)這些組件。否則需要使用 OnStartPage。

錯(cuò)誤處理
建議
錯(cuò)誤處理器將期待著意外情況。捕獲應(yīng)用程序每一部分中的錯(cuò)誤,并盡可能完整地記錄下來(lái)。好的日志對(duì)于跟蹤、隔離和疑難解答有重大意義。這些日志可以實(shí)現(xiàn)為文本文件或?qū)懭?NT 事件日志。在多數(shù)情況下,邊添加信息邊“冒出”錯(cuò)誤,是通知調(diào)用者已經(jīng)出錯(cuò)的有效途徑。冒出錯(cuò)誤使調(diào)用者可自由地與處理具體問(wèn)題的具體方法交互。

當(dāng)記錄錯(cuò)誤時(shí),提供盡可能多的有用信息至關(guān)重要?紤]包括以下幾點(diǎn):

當(dāng)前用戶環(huán)境(調(diào)用 Win32 API — GetUserName)
當(dāng)前線程 ID(調(diào)用 Win32 API — GetCurrentThreadId 或 Visual Basic 中的 App.ThreadId)
當(dāng)前時(shí)間(使用 Win32 GetTickCount,得到的是毫秒數(shù)據(jù))
傳遞至方法的參數(shù)
錯(cuò)誤源,包括方法名
為什么
根據(jù)我們的經(jīng)驗(yàn),好的錯(cuò)誤處理和記錄是隔離和診斷運(yùn)行時(shí)問(wèn)題的最有效途徑。

常見(jiàn)的陷阱
還記得 ASP 0115 錯(cuò)誤嗎? 但愿您不用和它苦苦斗爭(zhēng)了。 如果還在為其苦惱, 建議您參閱 Troubleshooting with the IIS Exception Monitor(英文)。

ASP 0115 錯(cuò)誤不是總出現(xiàn)在開(kāi)發(fā)人員的控制下 — 但多數(shù)時(shí)候是這樣,錯(cuò)誤處理可能已經(jīng)避免了很多這種情況的發(fā)生,還可能在其發(fā)生時(shí)幫助解決了它們。

總之,最大的問(wèn)題為跳過(guò)錯(cuò)誤處理或沒(méi)有包含有用的診斷信息。

在 COM 中,罕有跨越組件的界限傳播異常的情況。捕獲異常 — 但返回 HResults,以向調(diào)用者傳送失敗信息。

詳細(xì)信息
下面的文章提供了有關(guān)有效錯(cuò)誤處理的應(yīng)用示例:

Fitch & Mather Stocks: Web Application Design(英文)
全局變量
建議
避免在組件中使用全局變量。在 Visual Basic 術(shù)語(yǔ)中,這表示在標(biāo)準(zhǔn)的 .BAS 模塊中沒(méi)有 Public 或 Global 變量。

為什么
Global 變量并不是真正意義上的全局。每個(gè)線程都有自己的副本。如果幾種方法恰好在同一線程中執(zhí)行,它們將看到相同的變量;否則它們?cè)L問(wèn)的是這些變量的不同副本。這意味著您可能給一個(gè)全局變量賦了值(在線程 A 中),但其另一個(gè)用戶(在線程 B 中執(zhí)行)看不到新值。

其原因是 Visual Basic 內(nèi)部使用“線程本地存儲(chǔ) (TLS)”來(lái)引用全局變量。這意味著每個(gè)線程都有自己的 Public 變量的副本,并且因?yàn)樗嬖诙鄠(gè)副本,全局?jǐn)?shù)據(jù)并不是真正“全局的”。也就是說(shuō),恰好在同一線程中運(yùn)行的用戶才會(huì)訪問(wèn)到同一個(gè)變量,不論他們是否期望如此。

常見(jiàn)的陷阱
如果在標(biāo)準(zhǔn) .BAS 模塊中使用 Public 變量,當(dāng)不同線程向還想使用同一個(gè)數(shù)據(jù)的不同用戶請(qǐng)求提供服務(wù)時(shí),這個(gè)數(shù)據(jù)可能已被破壞了。

詳細(xì)信息
Visual Basic Programmer's Journal(英文)1999 年 6 月版中由 Matt Curland 所著的下列文章 是必讀的:

Black Belt Programming - Create Worker Threads in DLLs
COMponent Builder - Create Efficient Multithreaded Apps
另外,下面 Daniel Appleman 所著的文章 很好地概述了 Visual Basic 中多線程的工作原理: A Thread to Visual Basic(英文)

分布組件
建議
組件的分布涉及性能、可伸縮性和安全性問(wèn)題。相同組件的不同分布可能產(chǎn)生更高性能、更易伸縮和更易管理的配置。

下面的指南有助于提高在多臺(tái)計(jì)算機(jī)上分布組件時(shí)的性能和可伸縮性:

在 IIS 的同一框圍中運(yùn)行引用 ASP 內(nèi)置對(duì)象的組件。
在應(yīng)用程序服務(wù)器上運(yùn)行數(shù)據(jù)庫(kù)組件。
在哪一臺(tái)計(jì)算機(jī)上運(yùn)行業(yè)務(wù)組件很重要。倘若您去掉業(yè)務(wù)組件與任何 ASP 的耦合,您就可以根據(jù)您的應(yīng)用程序設(shè)計(jì)、計(jì)算機(jī)的可用性和測(cè)試,來(lái)自由選擇。
當(dāng)然還有例外。但這些是指南的好的開(kāi)始。

為什么
跨計(jì)算機(jī)分布組件使應(yīng)用程序可以滿足伸縮性要求。其次,上面提到的指南有助于實(shí)現(xiàn)應(yīng)用程序的性能和可伸縮性目標(biāo)。

對(duì)象引用 ASP 內(nèi)置對(duì)象,會(huì)與您的 Web 服務(wù)器進(jìn)行大量通訊,并且由于它們是表達(dá)層的一部分,因此它們就在那里。

數(shù)據(jù)庫(kù)或?qū)?shù)據(jù)極為敏感的邏輯可能在數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程中。將數(shù)據(jù)訪問(wèn)組件置于應(yīng)用程序服務(wù)器而非數(shù)據(jù)庫(kù)上,避免了組件之間的昂貴調(diào)用。相反,數(shù)據(jù)訪問(wèn)組件則利用 SQL Server 通信(如 TCP/IP)與數(shù)據(jù)庫(kù)更有效地通信。

常見(jiàn)的陷阱
您應(yīng)當(dāng)嘗試避免下列問(wèn)題:

當(dāng)橫向可伸縮性較為合適之后,繼續(xù)追求從您的計(jì)算機(jī)開(kāi)始的縱向可伸縮性。
忽視了防火墻的考慮(幫自己一個(gè)忙。如果計(jì)算機(jī)間的產(chǎn)品環(huán)境有防火墻,則在測(cè)試方案中添加防火墻。)
將引用 ASP 內(nèi)置對(duì)象的組件置于與 IIS 服務(wù)器分離的計(jì)算機(jī)上(回調(diào)和編組 ASP 內(nèi)置對(duì)象的成本很高。)
使用組件內(nèi)部的后期綁定(這產(chǎn)生對(duì) GetIdsOfNames 的額外調(diào)用,這在分布式應(yīng)用程序中可能很昂貴。盡量使用早期綁定。)
按引用傳遞參數(shù)(這產(chǎn)生更多的編組開(kāi)銷(xiāo)。盡可能“按值”傳遞參數(shù)。)
成功地從 IIS 調(diào)用遠(yuǎn)程 MTS 組件也可能很棘手。一個(gè)簡(jiǎn)單有效、既提高性能又簡(jiǎn)化安全性問(wèn)題的解決方案,是調(diào)用中間的 MTS/COM+ 軟件包/應(yīng)用程序。早期綁定可減少網(wǎng)絡(luò)路程段,提高性能。如果您使用“服務(wù)器”軟件包/應(yīng)用程序,則可以設(shè)置軟件包/應(yīng)用程序的運(yùn)行標(biāo)識(shí)。這個(gè)技術(shù)將在 KB 文章 159311 Instantiating Remote Components in Microsoft Transaction Server and Internet Information Server 中討論。

詳細(xì)信息
如果已經(jīng)解耦了服務(wù),特別是已使 ASP 在業(yè)務(wù)組件之外,則分布將相當(dāng)靈活。您就可以更多地考慮框圍,并根據(jù)需要分散組件以解決隨之而來(lái)的可伸縮性和性能問(wèn)題。如何知道?進(jìn)行測(cè)試。如何測(cè)試?請(qǐng)看下面的基本指南:

若要測(cè)試 Web 站點(diǎn)的可靠性,請(qǐng)剖析計(jì)算機(jī)并檢查錯(cuò)誤。
若要測(cè)試性能,請(qǐng)查看每秒可處理多少 ASP 請(qǐng)求。
若要測(cè)試可伸縮性,請(qǐng)?jiān)O(shè)置每秒需要處理多少 ASP 請(qǐng)求的閥值。用重要的工具考驗(yàn)應(yīng)用程序——添加用戶直到性能壞到不能接受為止。
加強(qiáng)對(duì)應(yīng)用程序的測(cè)試非常重要,因?yàn)樾枰┞哆\(yùn)轉(zhuǎn)條件和單瀏覽器測(cè)試中不會(huì)出現(xiàn)的其他問(wèn)題。
有關(guān)對(duì)應(yīng)用程序加強(qiáng)測(cè)試的詳細(xì)內(nèi)容, 請(qǐng)參閱 I Can't Stress It Enough -- Load Test Your ASP Application(英文)。

結(jié)論
正如所見(jiàn),有一些事情在整個(gè)開(kāi)發(fā)中需要時(shí)刻注意。在此,應(yīng)用程序指南所涉及的諸多因素已全部闡明,因?yàn)樗鼈冇兄趶氐妆苊鈬?yán)重失誤。在整個(gè)開(kāi)發(fā)周期中遵循本文中略述的幾個(gè)指南,不僅可以避免一些額外的工作,而且能夠提交可收縮的、可靠的、高性能的基于 ASP 組件的解決方案。




標(biāo)簽:ASP 組件向?qū)?/a>