Как использовать кэширование вывода в обработчике .ashx - PullRequest
25 голосов
/ 10 июля 2009

Как использовать кэширование вывода с обработчиком .ashx? В этом случае я выполняю тяжелую обработку изображений и хотел бы, чтобы обработчик кэшировался в течение минуты или около того.

Кроме того, у кого-нибудь есть какие-либо рекомендации по предотвращению разведения собак?

Ответы [ 5 ]

36 голосов
/ 10 июля 2009

Есть несколько хороших источников, но вы хотите кэшировать свою обработку на стороне сервера и на стороне клиента.

Добавление заголовков 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);

Что касается кэширования на стороне сервера, это другой монстр ... и есть много ресурсов для кэширования ...

11 голосов
/ 04 июня 2011

вы можете использовать вот так

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);
            }
        }
    }
6 голосов
/ 11 сентября 2014

Старый вопрос, но в ответе на самом деле не упоминалась обработка на стороне сервера.

Как и в победном ответе, я бы использовал это для 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, поскольку вместо веб-страницы вы используете 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);
}
4 голосов
/ 24 марта 2010

Я успешно использовал следующее и подумал, что стоит опубликовать здесь.

Ручное управление кэшем вывода страницы ASP.NET

С http://dotnetperls.com/cache-examples-aspnet

Настройка параметров кэширования в файлах Handler.ashx

Во-первых, вы можете использовать обработчики HTTP в ASP.NET для более быстрого доступа к серверу динамический контент, чем страницы веб-формы. Handler.ashx - это имя по умолчанию для общий обработчик ASP.NET. Тебе нужно использовать параметр HttpContext и получить доступ к ответу таким образом.

Пример кода:

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

C # для кэширования ответа на 1 час

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;
        }
    }
}
1 голос
/ 28 сентября 2016

Решение с OutputCachedPage работает нормально, однако за счет производительности, поскольку вам необходимо создать экземпляр объекта, производного от базового класса System.Web.UI.Page .

Простым решением будет использование Response.Cache.SetCacheability , как предлагается в некоторых из приведенных выше ответов. Однако для кэширования ответа на сервере (внутри Output Cache) необходимо использовать HttpCacheability.Server и установить VaryByParams или VaryByHeaders (обратите внимание, при использовании VaryByHeaders URL не может содержать строку запроса, поскольку кэш будет пропущен).

Вот простой пример (основан на 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;
        }
    }
}

Подсказка: вы отслеживаете кэширование в счетчиках производительности «Приложения ASP.NET__Total __ \ Итоговый объем кэша».

...