Вопрос по asp.net, ashx, caching – Как использовать кэширование вывода в обработчике .ashx

25

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

Кроме того, кто-нибудь есть какие-либо рекомендации о том, как предотвратить собачьей кучи?

Довольно похожая тема: / Stackoverflow.com вопросы / 745500 / .... hadi teo
Еще одна ссылка: Forums.asp.net / т / 1294848.aspx hadi teo

Ваш Ответ

5   ответов
35

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

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

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

Cheer Man - я чувствую твою боль, мы кешируем много разных вещей (только не эти изображения, как выясняется - это вызывает у нас проблемы!), И довольно регулярно вы получаете людей, жалующихся на несвоевременные изменения, даже если это только перерыв на несколько минут! Kieran Benton
Я выполнил много изображений из БД для миниатюр. Одна вещь, которую вы должны быть осторожны, это установка ожиданий конечного пользователя ... Пользователь будет обновлять изображение, а затем проверять действующий сайт ... хорошо, потому что браузеру сказали кэшировать изображение и даже не запрашивать его ... они не увидят там обновлений ... (потом они будут плакать обратно в dev ... и мы будем говорить, очисти кеш браузера ...) BigBlondeViking
Обязательно включите «Response.Cache.SetRevalidation (Web.HttpCacheRevalidation.None);» и "Response.Cache.SetValidUntilExpires (True);" если вы хотите убедиться, что они не могут запросить новое изображение при обновлении страницы. Также установите "Response.Cache.VaryByParams (" * ") = True;" если ваши обработчики должны поддерживать разные версии по параметру запроса. Carter Medlin
Спасибо - после прочтения оставленного выше комментария становится очевидным, что кэширование вывода не может быть использовано непосредственно в этой ситуации, поэтому будет идти с ручным решением на стороне сервера и с этим на стороне клиента. Kieran Benton
Re: MaxAge ... Codeproject.com / KB / Ajax / aspnetajaxtips.aspx Цитата: «В ASP.NET 2.0 есть ошибка, из-за которой нельзя изменить заголовок максимального возраста». frankadelic
1

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

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

Вот простой пример (на основеhttps: //support.microsoft.com/en-us/kb/32329):

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

pub,lic 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: вы наблюдаете за кэшированием в счетчиках производительности «Приложения ASP.NET__Total __ \ Итоговое значение кэша вывода».

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);
            }
        }
    }
Отличный рабочий человек .... отлично patel.milanb
4

что стоит публиковать здесь.

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

Отhttp: //dotnetperls.com/cache-examples-aspne

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

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

Пример кода:

<%@ 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;
        }
    }
}
Исправьте меня, если я ошибаюсь, но эти параметры не влияют только на кеш браузера. Я не думаю, что они влияют на кэш вывода IIS или ASP.NET RobSiklos
6

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

Как в победном ответе, я бы использовал это для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);
}
Черт, просто пошел, чтобы объявить это, и узнал, что я, должно быть, был здесь однажды, как и сейчас! Matt

Похожие вопросы