Как использовать кэширование вывода в обработчике .ashx
Как использовать кэширование вывода с помощью обработчика .ashx? В этом случае я выполняю тяжелую обработку изображений и хотел бы, чтобы обработчик был кэширован в течение минуты или около того.
Кроме того, есть ли у кого-нибудь какие-либо рекомендации о том, как предотвратить собаку?
Ответы
Ответ 1
Есть несколько хороших источников, но вы хотите кэшировать серверную обработку и клиентскую сторону.
Добавление заголовков 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);
Что касается кеширования на стороне сервера, это другой монстр... и есть много ресурсов кэширования...
Ответ 2
вы можете использовать это как
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);
}
}
}
Ответ 3
Я использовал следующее с успехом и считал целесообразным опубликовать здесь.
Управление кешем вывода страницы ASP.NET вручную
От http://dotnetperls.com/cache-examples-aspnet
Настройка параметров кеша в файлах Handler.ashx
Во-первых, вы можете использовать обработчики HTTP в ASP.NET для более быстрого доступа к серверу динамический контент, чем страницы веб-формы. Handler.ashx - это имя по умолчанию для общий обработчик ASP.NET. Тебе нужно для использования параметра HttpContext и доступ к ответу таким образом.
Выбранный пример кода:
<%@ WebHandler Language="C#" Class="Handler" %>
С# для кэширования ответа в течение 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;
}
}
}
Ответ 4
Старый вопрос, но ответ на самом деле не упоминал о серверной обработке.
Как и в выигрышном ответе, я использовал бы это для 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", а 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);
}
Ответ 5
Решение с OutputCachedPage работает отлично, но с ценой производительности, поскольку вам нужно создать экземпляр объекта, полученного из System.Web.UI.Page базовый класс.
Простым решением было бы использовать Response.Cache.SetCacheability, как это было предложено в некоторых из приведенных выше ответов. Однако для ответа на кеширование на сервере (внутри выходного кэша) необходимо использовать HttpCacheability.Server и установить VaryByParams или VaryByHeaders (обратите внимание, что при использовании URL VaryByHeaders не может содержать строку запроса, так как кеш будет пропущен).
Вот простой пример (на основе 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 __\Output Cache Total".