如何在 .ashx 处理程序上使用输出缓存

Posted

技术标签:

【中文标题】如何在 .ashx 处理程序上使用输出缓存【英文标题】:How to use output caching on .ashx handler 【发布时间】:2010-11-09 17:37:05 【问题描述】:

如何通过 .ashx 处理程序使用输出缓存?在这种情况下,我正在进行一些繁重的图像处理,并希望将处理程序缓存一分钟左右。

另外,有没有人对如何防止打狗有任何建议?

【问题讨论】:

非常相似的线程:***.com/questions/745500/…. 另一个参考:forums.asp.net/t/1294848.aspx 【参考方案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);

至于服务器端缓存是一个不同的怪物......而且那里有很多缓存资源......

【讨论】:

谢谢 - 从上面的评论中可以看出,在这种情况下也不能直接使用输出缓存,因此将使用手动服务器端解决方案和客户端解决方案。 我从数据库中为缩略图提供了很多图像服务。您需要注意的一件事是设置最终用户的期望......用户会更新图像,然后去查看实时站点......好吧,因为浏览器被告知要缓存图像,甚至不要求它......他们不会看到更新...(然后他们会哭着回到开发人员那里...我们会说清除您的浏览器缓存...) 干杯人 - 我感受到你的痛苦,我们缓存了很多不同的东西(只是不是这些图像,因为事实证明 - 这给我们带来了问题!)而且你经常让人们抱怨非立即更改,即使只有几分钟的超时! Re: MaxAge...codeproject.com/KB/ajax/aspnetajaxtips.aspx 引用:“在 ASP.NET 2.0 中有一个错误,您无法更改 max-age 标头。” 确保包含“Response.Cache.SetRevalidation(Web.HttpCacheRevalidation.None);”和“Response.Cache.SetValidUntilExpires(True);”如果您想确保他们在刷新页面时无法请求新图像。还要设置 "Response.Cache.VaryByParams("*") = True;"如果您的处理程序应该通过查询参数维护不同的版本。【参考方案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】:

老问题,但答案并没有真正提到服务器端处理。

正如在获胜答案中一样,我会将其用于 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】:

我成功使用了以下内容,并认为值得在这里发布。

手动控制 ASP.NET 页面输出缓存

来自http://dotnetperls.com/cache-examples-aspnet

在 Handler.ashx 文件中设置缓存选项

首先,您可以使用 HTTP 处理程序 在 ASP.NET 中获得更快的服务器方式 动态内容比 Web 表单页面。 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;
        
    

【讨论】:

如果我错了,请纠正我,但这些选项不会只影响浏览器缓存。我认为它们对 IIS 或 ASP.NET 输出缓存没有任何影响【参考方案5】:

使用 OutputCachedPage 的解决方案效果很好,但是以性能为代价,因为您需要实例化一个派生自 System.Web.UI.Page 的对象基类。

一个简单的解决方案是使用 Response.Cache.SetCacheability,正如上述一些答案所建议的那样。但是,要在服务器(在输出缓存内)缓存响应,需要使用 HttpCacheability.Server,并设置 VaryByParamsVaryByHeaders (注意当使用 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 Applications__Total__\Output Cache Total”中监控缓存。

【讨论】:

以上是关于如何在 .ashx 处理程序上使用输出缓存的主要内容,如果未能解决你的问题,请参考以下文章

使用 ashx 处理程序从 SQL 表中读取 BLOB 文件时如何在 Edge 中查看文件

在 MVC 中如何通过 jquery 调用 .ashx 处理程序文件

asp.net 一般处理程序(ashx)如何多次接收上传文件(多文件批量上传)

asp.net 一般处理程序(ashx)如何多次接收上传文件(多文件批量上传)

支持 JSONP 的 ASP.NET 通用 HTTP 处理程序 (.ashx)

如何使用缓存