web-dev-qa-db-ja.com

.ashxハンドラーで出力キャッシュを使用する方法

.ashxハンドラーで出力キャッシュを使用するにはどうすればよいですか?この場合、私はいくつかの重い画像処理を行っており、ハンドラーを1分ほどキャッシュしたいと思います。

また、ドッグパイルを防ぐ方法について誰かが何かアドバイスはありますか?

25
Kieran Benton

いくつかの優れたソースがありますが、処理サーバー側とクライアント側をキャッシュする必要があります。

HTTPヘッダーを追加すると、クライアント側のキャッシュに役立つはずです

開始するためのいくつかのResponseヘッダーがあります。

目的のパフォーマンスが得られるまで、何時間もかけて調整することができます

//Adds document content type
context.Response.ContentType = currentDocument.MimeType;
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
context.Response.Cache.SetMaxAge(new TimeSpan(0,10,0)); 
context.Response.AddHeader("Last-Modified", currentDocument.LastUpdated.ToLongDateString());

// Send back the file content
context.Response.BinaryWrite(currentDocument.Document);

別のモンスターであるサーバー側のキャッシングに関しては...そしてそこにはたくさんのキャッシングリソースがあります...

36
BigBlondeViking

あなたはこのように使うことができます

public class CacheHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters
            {
                Duration = 60,
                Location = OutputCacheLocation.Server,
                VaryByParam = "v"
            });
            page.ProcessRequest(HttpContext.Current);
            context.Response.Write(DateTime.Now);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        private sealed class OutputCachedPage : Page
        {
            private OutputCacheParameters _cacheSettings;

            public OutputCachedPage(OutputCacheParameters cacheSettings)
            {
                // Tracing requires Page IDs to be unique.
                ID = Guid.NewGuid().ToString();
                _cacheSettings = cacheSettings;
            }

            protected override void FrameworkInitialize()
            {
                // when you put the <%@ OutputCache %> directive on a page, the generated code calls InitOutputCache() from here
                base.FrameworkInitialize();
                InitOutputCache(_cacheSettings);
            }
        }
    }
11
JeffZhnn

古い質問ですが、答えはサーバー側の処理については実際には言及していませんでした。

勝者の答えのように、私はこれをclient sideに使用します:

context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(10)); 

server sideの場合、Webページの代わりにashxを使用しているため、出力をContext.Responseに直接書き込んでいると想定しています。

その場合、次のようなものを使用できます(この場合、パラメーター "q"に基づいて応答を保存し、Imはスライディングウィンドウの有効期限を使用します)

using System.Web.Caching;

public void ProcessRequest(HttpContext context)
{
    string query = context.Request["q"];
    if (context.Cache[query] != null)
    {
        //server side caching using asp.net caching
        context.Response.Write(context.Cache[query]);
        return;
    }

    string response = GetResponse(query);   
    context.Cache.Insert(query, response, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(10)); 
    context.Response.Write(response);
}
6

私は以下を成功裏に使用し、ここに投稿する価値があると思いました。

ASP.NETページ出力キャッシュを手動で制御する

から http://dotnetperls.com/cache-examples-aspnet

Handler.ashxファイルでのキャッシュオプションの設定

まず、ASP.NETでHTTPハンドラーを使用して、Webフォームページよりも高速に動的コンテンツをサーバー化できます。 Handler.ashxは、ASP.NET汎用ハンドラーのデフォルト名です。 HttpContextパラメーターを使用して、その方法で応答にアクセスする必要があります。

抜粋したサンプルコード:

<%@ WebHandler Language="C#" Class="Handler" %>

応答を1時間キャッシュするC#

using System;
using System.Web;

public class Handler : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        // Cache this handler response for 1 hour.
        HttpCachePolicy c = context.Response.Cache;
        c.SetCacheability(HttpCacheability.Public);
        c.SetMaxAge(new TimeSpan(1, 0, 0));
    }

    public bool IsReusable {
        get {
            return false;
        }
    }
}
4
John K

OutputCachedPageを使用したソリューションは正常に機能しますが、System.Web.UIから派生したオブジェクトをインスタンス化する必要があるため、パフォーマンスが犠牲になります。 .Page基本クラス。

簡単な解決策は、上記の回答のいくつかで示唆されているように、Response.Cache.SetCacheabilityを使用することです。ただし、応答をサーバー(出力キャッシュ内)にキャッシュするには、HttpCacheability.Serverを使用し、VaryByParamsを設定する必要があります。 )またはVaryByHeadersVaryByHeadersを使用する場合、キャッシュがスキップされるため、URLにクエリ文字列を含めることはできません)。

簡単な例を次に示します( https://support.Microsoft.com/en-us/kb/32329 に基づく):

<%@ WebHandler Language="C#" Class="cacheTest" %>
using System;
using System.Web;
using System.Web.UI;

public class cacheTest : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        TimeSpan freshness = new TimeSpan(0, 0, 0, 10);
        DateTime now = DateTime.Now; 
        HttpCachePolicy cachePolicy = context.Response.Cache;

        cachePolicy.SetCacheability(HttpCacheability.Public);
        cachePolicy.SetExpires(now.Add(freshness));
        cachePolicy.SetMaxAge(freshness);
        cachePolicy.SetValidUntilExpires(true);
        cachePolicy.VaryByParams["id"] = true;

        context.Response.ContentType = "application/json";
        context.Response.BufferOutput = true;

        context.Response.Write(context.Request.QueryString["id"]+"\n");
        context.Response.Write(DateTime.Now.ToString("s"));
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

ヒント:パフォーマンスカウンター「ASP.NETApplications__Total __\OutputCacheTotal」でキャッシュを監視します。

1
knee-cola