2012-09-02 14 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. 

アム:この単純なケースでは私の問題を示していますか?再利用を打ち負かすことのできる何か他のものがありますか?違いがあれば、Silverlightアプリケーションからハンドラが呼び出されています。

+0

はどのようにあなたのアプリケーションにあなたのハンドラを取り付けていますか? web.configまたはプログラムによって – Jacob

+0

これは私の最初のそのようなアプリです。私はVisual Studioで新しいASP.NET Webサイトプロジェクトを作成しました。サーバーを実行するには、Visual StudioからDebugを実行しています。 –

+0

実行するために 'MyRequestHandler'をどのように設定したかを尋ねています。例えば、あなたのweb.configに設定されているのですか、それを登録する 'Global.asax'のコードがありますか? – Jacob

答えて

3

IsReusableは保証しません。

ハンドラをリファクタリングして、すべてのクロスリクエスト状態を別のクラスに入れます。とにかくウェブアプリケーションのクロスリクエスト状態を明確に分離するには、ベストプラクティスが危険です。

+0

高価なセットアップでは、最大100 MBのメモリを割り当てる必要があり、それ以上の設計はできないとしましょう。割り当ては避けられません。私はそれぞれの要求に対して100 MBを再割り当てしたくありません。そのメモリポインタを永続化するために「異なるクラス」を使用することができるので、複数のリクエスト(または複数のハンドラ)からアクセスできますか? –

+0

あなたの状態保持クラスのインスタンスを指す静的変数を使用してください。または、httpアプリケーション辞書に入れます。どんな種類の静的記憶域も行います(スレッドセーフであることを確認してください)。 – usr

+1

良い答え。ありがとうございました。 –

1

スレッドセーフであれば、とにかく再利用するよりも上手く行くことができます。

  1. まずハンドラのインスタンスが作成されます。その後、真IsReusableリターンが

  2. ProcessRequestが呼び出されています。
  3. をもう一度使用するプールに入れることができます。

これは、同じURIへの複数の同時呼び出しがある場合は、そのようなハンドラが複数必要になることを保証します同時にそれらを処理するために作成されます。

このアプローチの良い点は、(プーリングが行われたとき)ハンドラは実際にスレッドセーフである必要はないということです。

あなたの問題は解決していないので、私たちは2つの方法のどちらかでうまくいくでしょう。

1つは、すべての機能を別のクラスに入れることです。次に、ハンドラは、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 
    } 
} 

上記のクラスでは、あなたはそれが現在MyRequestHandlerを指しMyRequestHandlerFactoryを参照するのWeb.Configを変更することができ、かつそれは完全に動作します。

(あなたが、その場合には、思ったようスレッドセーフとして実際にいないでない限り - !oopsie)

関連する問題