6

私は現在、カスタムHttpHandlerを開発しています(CSSを圧縮/結合するためですが、この質問には関係ありません)。

私は、誰もが知っているような単純なreusable=true同期HttpHandlerから始めました。

今、私はそれを非同期ハンドラーに改善しようとしています(IO機能を使用し、非常に忙しいWebサイトで使用されているため)。

私の最初の試み(そしてこれはうまくいくようです):

Action<HttpContext> asyncProcessRequest;

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
    asyncProcessRequest = new Action<HttpContext>(ProcessRequest);
    return asyncProcessRequest.BeginInvoke(context, cb, extraData);
}

public void EndProcessRequest(IAsyncResult result)
{
    asyncProcessRequest.EndInvoke(result);
}

public virtual void ProcessRequest(HttpContext context)
{
    // real work
}

これは再利用不可能なhttphandlerです(私が読んだところによると、このハンドラーには状態(asyncProcessRequestフィールド)があるため、IsReusableはfalseである必要があります。

今、私はこれを再利用可能にしたいです。したがって、私の最初の考えは、次のようなIAsyncResult/Actionの辞書を作成することでした。

IDictionary<IAsyncResult, Action<HttpContext>> asyncProcessRequests;

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
    if (asyncProcessRequests == null)
    {
        asyncProcessRequests = new Dictionary<IAsyncResult, Action<HttpContext>>();
    }

    var request = new Action<HttpContext>(ProcessRequest);
    var result = request.BeginInvoke(context, cb, extraData);
    asyncProcessRequests.Add(result, request);
    return result;
}

public void EndProcessRequest(IAsyncResult result)
{
    Action<HttpContext> action;
    if (asyncProcessRequests.TryGetValue(result, out action))
    {
        action.EndInvoke(result);
    }
}

これは正しいパターンですか?または私は道を離れていますか?

動作しているようですが(エラーや奇妙な動作は発生していません)、これを本番環境に移行する前に、これらのHttpハンドラーの作成に私よりも経験のある人に確認したいと思います。

前もって感謝します!

4

2 に答える 2

4

一般に、非同期パターンの場合、BeginXxxメソッドに渡すstateパラメーターを最後のパラメーターとして使用する必要があります(これを呼び出しましたextraData)。

したがって、(元の)ヘルパークラスextraDataと、リクエストの終了を処理するために必要な追加の状態を保持するヘルパークラスを作成することをお勧めします。

ただし、特定のケースでは、非同期パターンを使用して何も加速していないと思います。それは機能しますが、基本的にオーバーヘッドを追加するだけです。これは、非同期方式でデリゲートを呼び出しているためです。これは、呼び出しを処理するためにスレッドプールに呼び出しをディスパッチするだけです。したがって、非同期呼び出しを介して複数のデリゲートを同時に実行していない限り、大きなメリットはありません。Webリクエストはすでにマルチスレッド化されているため、これがパフォーマンスに役立つとは思いません。逆に、スレッドプールが不足するリスクがあります。

正確で効率的な非同期処理は簡単ではありません。ファイルやネットワーク接続からのデータの読み取りなど、本質的に非同期の処理を実行している場合や、非同期呼び出しをサポートする外部コンポーネント(Webサービス呼び出しやデータベースなど)を呼び出す場合に、この利点を活用できます。

于 2010-02-05T15:32:41.417 に答える
2

私の記憶が正しければ、IsReusableはASP.NETに対して、要求の処理後にハンドラーを破棄してはならず、同じインスタンスを後続の要求の処理に使用できることを示しています。つまり、ハンドラオブジェクトの1つのインスタンスは、複数のリクエストを同時に処理しません。

于 2010-02-05T15:24:08.043 に答える