HttpHandler開發的兩個重點問題

2021-05-22 06:37:05 字數 4970 閱讀 7076

大家在用httphandler的時候,一般都會有兩個大的疑問(當然,前提是你有鑽研精神的話,呵呵)

老實說,這個屬性很多人都感興趣,但搞懂的人確實不多。msdn中的介紹也是不知所以然。

獲取乙個值,該值指示其他請求是否可以使用ihttphandler例項。該屬性預設為false

我來這麼說吧,首先我們為什麼使用自定義的handler呢?簡單的說,我們是希望能接管掉某些請求,對吧?最常見的應用如下

知道上述的需求之後,我們再來看一下後台的設計。httphandler其實就是實現了ihttphandler介面的乙個型別,它要工作,就必須通過asp.net所提供的一些所謂的factory去建立例項,然後呼叫它的processrequest方法。其實就這麼簡單

因為建立物件例項在伺服器肯定是需要占用資源的,那麼我們就勢必要考慮這些請求能不能在一定程式上去復用。這就是isreusable的初衷

事實上,我們對這種復用並不會陌生。平常我們就知道物件池和連線池的技術。handler的reuse也是乙個池的概念。

好了,說了這麼一堆的概念,我們來講一講該屬性設定為true和設定為false的區別。

我們來看乙個例子。為了做測試,我寫了如下**

using system;

using system.collections.generic;

using system.web;

using system.io;

using system.threading;

#region ihttphandler 成員

**很簡單,我通過乙個文字檔案的方式記錄物件什麼建立的,什麼時候發起請求和結束請求的。現在我先設定isreusable為false

在除錯之前,我們還需要設定一下web.config,新增乙個httphandler的註冊

這裡作為演示目的,我就犧牲一下自己,用這個handler來監聽所有字尾名為chenxizhang的請求

開啟瀏覽器,輸入類似下面這樣的**http://localhost:6994/test.chenxizhang

快速地重新整理幾次,然後關閉瀏覽器。找到**根目錄下面的乙個log.txt檔案,會看到下面的文字

2009/6/15 11:28:30物件例項被建立

2009/6/15 11:28:30當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:28:30結束呼叫

2009/6/15 11:28:31物件例項被建立

2009/6/15 11:28:31當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:28:31結束呼叫

2009/6/15 11:28:31物件例項被建立

2009/6/15 11:28:31當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:28:31結束呼叫

2009/6/15 11:28:32物件例項被建立

2009/6/15 11:28:32當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:28:32結束呼叫

2009/6/15 11:28:32物件例項被建立

2009/6/15 11:28:32當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:28:32結束呼叫

2009/6/15 11:28:32物件例項被建立

2009/6/15 11:28:32當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:28:32結束呼叫

2009/6/15 11:28:32物件例項被建立

2009/6/15 11:28:32當前被呼叫的請求是:/test.chenxizhang

我們可以看到,每次都請求都需要建立例項

然後,我們去修改一下isreusable屬性為true,再執行,就可以看到下面這樣的輸出結果了

2009/6/15 11:23:34物件例項被建立

2009/6/15 11:23:34當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:23:34結束呼叫

2009/6/15 11:24:40當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:40結束呼叫

2009/6/15 11:24:40當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:40結束呼叫

2009/6/15 11:24:40當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:40結束呼叫

2009/6/15 11:24:40當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:40結束呼叫

2009/6/15 11:24:40當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:40結束呼叫

2009/6/15 11:24:41當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:41結束呼叫

2009/6/15 11:24:41當前被呼叫的請求是:/test.chenxizhang

2009/6/15 11:24:41結束呼叫

也就是說,物件只被建立了一次。後面呼叫就重複利用了。這樣看起來是不是還不錯呢?

通常意義上說,isreusable設定為true可以提高效能,尤其是說這種handler初始化的時候需要做很多事情的情況下。但為什麼預設又設定為false呢?

因為如果設定為true,也就是所有有使用者,所有請求都共享乙個物件例項,那麼可能造成什麼問題呢?

我同時還想到另外乙個問題,假設isreusable是設定為true的,同時又假設它的processrequest卻又需要比較長時間才能完成。那麼會怎麼樣呢?

就是說前乙個請求還沒有完成,這時候又有第二個請求過來。該如何處理?

using system;

using system.collections.generic;

using system.web;

using system.io;

using system.threading;

using system.web.sessionstate;

#region ihttphandler 成員

上面的**中,我加入乙個讓當前執行緒休眠的**:讓它休眠10秒鐘。此時,我們來重新整理瀏覽器看看會怎麼樣

2009/6/15 12:05:59物件例項被建立

2009/6/15 12:05:59當前被呼叫的請求是:/ie.chenxizhang

2009/6/15 12:06:02物件例項被建立

2009/6/15 12:06:02當前被呼叫的請求是:/google.chenxizhang

2009/6/15 12:06:09結束呼叫 //這一句是ie.chenxizhang結束了

2009/6/15 12:06:12結束呼叫 //這一句是google.chenxizhang結束了

我用了兩個瀏覽器來模擬兩個使用者的操作。你會驚奇地發現,雖然我們設定為true,但仍然建立了多個例項。這又是咋回事呢

這個問題要這麼理解了:因為現在是執行緒阻塞了,所以asp.net引擎會檢測到這一點,他必須建立另外例項出來,否則很顯然,第二個請求就必須等第乙個請求結束之後才能開始工作,這顯然是不可以接受的,這個現象,在大容量使用者併發的時候可能是乙個災難

好吧,再繞回來說,假如我們的操作時間比較長,但什麼時候又不需要建立多個例項呢?答案就是說,如果非同步的話。

也正因為可能會有非同步的情況,所以就出現了我們剛才所說的執行緒安全性問題。可以配合鎖定機制避免一些問題。

所以,針對isreusable屬性,我總結如下:

有些朋友在使用handler的時候,念念不忘原先在頁面程式設計中的會話狀態(session),乙個典型的問題就是:在handler裡面能不能使用我的使用者狀態資訊呀?

例如,能不能新增下面這樣的**呢

context.response.write("當前使用者的狀態值為:" + context.session["id"].tostring());

答案是:當然可以。

先別忙著樂,雖然可以新增這樣的**,但它預設卻無法工作。你會收到下面這樣的錯誤訊息:未將物件設定到引用的例項

但是,假設你就是認準了這個非用不可,那麼你也可以通過下面的方式來實現

為該型別實現乙個介面:irequiressessionstate

這個介面不需要有任何方法實現,只需要定義一下就可以了。所以整個案例的**,如下

using system;

using system.collections.generic;

using system.web;

using system.io;

using system.threading;

using system.web.sessionstate;

#region ihttphandler 成員

HttpHandler開發的兩個重點問題

大家在用httphandler的時候,一般都會有兩個大的疑問 當然,前提是你有鑽研精神的話,呵呵 1.isreusable到底什麼意思?老實說,這個屬性很多人都感興趣,但搞懂的人確實不多。msdn中的介紹也是不知所以然。獲取乙個值,該值指示其他請求是否可以使用 ihttphandler 例項。該屬性...

httphandler的配置幾個屬性介紹

偷懶。直接從微軟官網摘下來 屬性屬性 說明 path 必選的屬性。指定路徑屬性可以包含單個 url 路徑或簡單的萬用字元字串 如 aspx type 必選的屬性。指定逗號分隔的類 程式集組合。asp.net 首先在應用程式的專用 bin 目錄中搜尋程式集 dll,然後在系統程式集快取中搜尋程式集 d...

開發兩則小記

var wshshell newactivexobject wscript.shell var path if getosversion 64 path wshshell.regread hkey local machine software wow6432node pzdnsoft path el...