2012-09-02 33 views
5

我有一個IHttpHandler,我相信可以從重用中受益,因爲它設置昂貴,並且是線程安全的。但是每個請求都會創建一個新的處理程序。我的處理程序沒有被重用。IHttpHandler IsReusable,但沒有得到重用

以下是我的簡單測試用例,沒有昂貴的設置。這個簡單的例子演示了我的問題:

public class MyRequestHandler : IHttpHandler 
{ 
    int nRequestsProcessed = 0; 

    public bool IsReusable 
    { 
     get { return true; } 
    } 

    public void ProcessRequest(HttpContext context) 
    { 
     nRequestsProcessed += 1; 
     Debug.WriteLine("Requests processed by this handler: " + nRequestsProcessed); 
     context.Response.ContentType = "text/plain"; 
     context.Response.Write("Hello World"); 
    } 
} 

Requests processed by this handler: 1 
Requests processed by this handler: 1 
Requests processed by this handler: 1 
Requests processed by this handler: 1... at least 100 times. I never see > 1. 

我誤解了IsReusable的工作原理嗎?還有什麼可以打敗重用嗎?我的處理程序正在從Silverlight應用程序調用,如果這有所幫助。

+0

你是如何處理程序安裝到您的應用程序?通過web.config或編程? – Jacob

+0

這是我第一個這樣的應用程序。我在Visual Studio中創建了一個新的ASP.NET Web站點項目。爲了運行服務器,我正在運行Visual Studio中的Debug。 –

+0

我在問你如何配置'MyRequestHandler'運行。例如,它是在你的web.config中配置的,還是你有'Global.asax'中的代碼來註冊它? – Jacob

回答

3

IsReusable不是保證。

只是重構你的處理程序,並將所有的交叉請求狀態放入不同的類。無論如何,在最佳實踐清楚地分離web應用程序中的交叉請求狀態,因爲它是危險的。

+0

我的昂貴的設置涉及分配高達100 MB的內存,並且假設它不能設計得更好,所以分配是不可避免的。我不想爲每個請求重新分配100 MB。我可以使用什麼「不同的類」來持久化內存指針,以便可以通過多個請求(或多個處理程序)來訪問它? –

+0

只需使用指向您的狀態持有類的實例的靜態變量即可。或者把它放在http應用程序字典中。任何類型的靜態存儲都可以(確保是線程安全的,順便說一下)。 – usr

+1

很好的答案。謝謝。 –

1

如果它是線程安全的,那麼無論如何你都可以比重用更好。

IsReusable返回true,則:創建處理程序的

  1. 首先一個實例。
  2. 它的ProcessRequest被調用。
  3. 可能被放入池中再次使用。

這意味着它可以減少重複的建立成本,但不一定(不保證),而不是完全 - 如果有多個併發調用到同一個URI,那麼將需要有幾個這樣的處理程序創建來同時處理它們。

這種方法的好處是(當池發生時),處理程序實際上不必是線程安全的。

既然是你的,但我們可以通過以下兩種方法中的一種來改善。

一,將你的所有功能放到另一個類中。然後,處理程序可以只是一個細長的類,其中ProcessRequest會通過該類到該靜態實例。

同樣,我們可以用一個IHttpHandlerFactory當前類做到這一點:

public class MyRequestHandlerFactory : IHttpHandlerFactory 
{ 
    private static MyRequestHandler SingletonHandler = new MyRequestHandler(); 
    IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated) 
    { 
    return SingletonHandler; 
    } 
    void ReleaseHandler(IHttpHandler handler) 
    { 
    //do nothing 
    } 
} 

有了上面的類,你可以改變web.config中參考MyRequestHandlerFactory目前它是指MyRequestHandler和它會完美地工作。

(除非你是不是真正的線程安全的,你想,在這種情況下 - !oopsie)