26

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

また、ドッグパイルを防ぐ方法について何か推奨事項はありますか?

4

5 に答える 5

36

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

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

開始するためのいくつかの応答ヘッダーを次に示します。

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

//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);

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

于 2009-07-10T14:23:01.170 に答える
11

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

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);
            }
        }
    }
于 2011-06-04T04:56:42.767 に答える
7

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

勝利の答えのように、これを次の目的で使用します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」に基づいて応答を保存し、スライディングウィンドウの有効期限を使用します)

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);
}
于 2014-09-10T22:06:54.290 に答える
1

The solution with the OutputCachedPage works fine, however at a price of the performance, since you need to instantiate an object derived from the System.Web.UI.Page base class.

A simple solution would be to use the Response.Cache.SetCacheability, as suggested by some of the above answers. However for the response to be cached at the server (inside Output Cache) one needs to use HttpCacheability.Server, and set a VaryByParams or VaryByHeaders (note that when using VaryByHeaders URL can't contain a query string, since the cache will be skipped).

Here's a simple example (based on https://support.microsoft.com/en-us/kb/323290):

<%@ 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;
        }
    }
}

Hint: you monitor the caching in the Performance Counters "ASP.NET Applications__Total__\Output Cache Total".

于 2016-09-28T12:03:43.990 に答える