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

Asp.net 如何在.ashx处理程序上使用输出缓存,asp.net,caching,ashx,Asp.net,Caching,Ashx,如何将输出缓存与.ashx处理程序一起使用?在本例中,我正在进行一些繁重的图像处理,希望将处理程序缓存一分钟左右 另外,有没有人对如何防止狗堆有什么建议?有一些很好的来源,但您希望缓存处理服务器端和客户端 添加HTTP头应该有助于客户端缓存 下面是一些要开始使用的响应标题 您可以花费数小时调整它们,直到获得所需的性能 //Adds document content type context.Response.ContentType = currentDocument.MimeType; cont

如何将输出缓存与.ashx处理程序一起使用?在本例中,我正在进行一些繁重的图像处理,希望将处理程序缓存一分钟左右


另外,有没有人对如何防止狗堆有什么建议?

有一些很好的来源,但您希望缓存处理服务器端和客户端

添加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);

至于服务器端缓存,这是一个不同的怪物。。。还有大量的缓存资源

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

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

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

首先,您可以使用HTTP处理程序 在ASP.NET中以更快的方式访问服务器 动态内容比Web表单页面更重要。 Handler.ashx是的默认名称 ASP.NET通用处理程序。你需要 使用HttpContext参数和 以这种方式访问响应

摘录的示例代码:

<%@ WebHandler Language="C#" Class="Handler" %>
你可以这样用

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);
            }
        }
    }
公共类缓存处理程序:IHttpHandler
{
公共void ProcessRequest(HttpContext上下文)
{
OutputCachedPage=新的OutputCachedPage(新的OutputCachedParameters
{
持续时间=60,
Location=OutputCacheLocation.Server,
VaryByParam=“v”
});
ProcessRequest(HttpContext.Current);
context.Response.Write(DateTime.Now);
}
公共布尔可重用
{
得到
{
返回false;
}
}
私有密封类OutputCachedPage:第页
{
私有输出缓存参数\u缓存设置;
公共OutputCachedPage(OutputCacheParameters缓存设置)
{
//跟踪要求页面ID是唯一的。
ID=Guid.NewGuid().ToString();
_cacheSettings=缓存设置;
}
受保护的覆盖void FrameworkInitialize()
{
//当您将指令放在页面上时,生成的代码从这里调用InitOutputCache()
base.FrameworkInitialize();
InitOutputCache(_cacheSettings);
}
}
}

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

与获奖答案一样,我会将其用于
客户端

context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(10)); 
对于
服务器端
,由于您使用的是ashx而不是网页,因此我假设您直接将输出写入
上下文.Response

在这种情况下,您可以使用类似的方法(在这种情况下,我希望根据参数“q”保存响应,并且我使用滑动窗口过期)


带有OutputCachedPage的解决方案运行良好,但要以性能为代价,因为您需要实例化从System.Web.UI.Page基类派生的对象

一个简单的解决方案是使用Response.Cache.SetCacheability,正如上面一些答案所建议的那样。但是,要在服务器(输出缓存内部)缓存响应,需要使用HttpCacheability.server,并设置VaryByParamsVaryByHeaders(请注意,使用VaryByHeaders时,URL不能包含查询字符串,因为缓存将被跳过)

下面是一个简单的示例(基于):


使用制度;
使用System.Web;
使用System.Web.UI;
公共类cacheTest:IHttpHandler
{
公共void ProcessRequest(HttpContext上下文)
{
TimeSpan新鲜度=新的TimeSpan(0,0,0,10);
DateTime now=DateTime.now;
HttpCachePolicy cachePolicy=context.Response.Cache;
cachePolicy.SetCacheability(HttpCacheability.Public);
SetExpires(now.Add(freshness));
cachePolicy.SetMaxAge(新鲜度);
cachePolicy.SetValidUntilExpires(true);
cachePolicy.VaryByParams[“id”]=true;
context.Response.ContentType=“应用程序/json”;
context.Response.BufferOutput=true;
context.Response.Write(context.Request.QueryString[“id”]+“\n”);
context.Response.Write(DateTime.Now.ToString(“s”);
}
公共布尔可重用
{
得到
{
返回false;
}
}
}

提示:您可以在性能计数器“ASP.NET应用程序\uuuuuuu总计\uuuuuuuu\输出缓存总计”中监视缓存。

非常类似的线程:。另一个参考:谢谢-阅读上面留下的注释,很明显,在这种情况下也不能直接使用输出缓存,因此,我们将使用手动服务器端解决方案和这个客户端解决方案。我做了大量的图像服务,在数据库外提供缩略图。你需要注意的一件事是设定最终用户的期望。。。用户将更新一个图像,然后去查看实时站点。。。因为浏览器被告知缓存图像,甚至不要求它。。。他们不会看到有更新。。。(然后他们会向dev哭诉…我们会说清除浏览器缓存…)干杯,伙计-我感觉到了你的痛苦,我们缓存了很多不同的东西(只是结果不是这些图片-这给我们带来了问题!)而且你经常会让人们抱怨非即时的更改,即使只是几分钟的超时!回复:MaxAge。。。引用:“ASP.NET 2.0中存在一个无法更改最大年龄头的错误。”如果您需要,请确保包括“Response.Cache.SetRevalidation(Web.HttpCacheRevalidation.None);”和“Response.Cache.setvalidUntileExpires(True);”
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(10)); 
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);
}
<%@ 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;
        }
    }
}