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

发布于 2024-07-26 04:36:14 字数 98 浏览 7 评论 0原文

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

另外,有人对如何防止狗堆有任何建议吗?

How can I use output caching with a .ashx handler? In this case I'm doing some heavy image processing and would like the handler to be cached for a minute or so.

Also, does anyone have any recommendations on how to prevent dogpiling?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

递刀给你 2024-08-02 04:36:14

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

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

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

There are some good sources but you want to cache you processing server side and client-side.

Adding HTTP headers should help in the client side caching

here are some Response headers to get started on..

You can spend hours tweaking them until you get the desired performance

//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);

As for server side caching that is a different monster... and there are plenty of caching resources out there...

对岸观火 2024-08-02 04:36:14

你可以这样使用

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);
            }
        }
    }

you can use like this

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);
            }
        }
    }
也只是曾经 2024-08-02 04:36:14

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

正如获胜答案一样,我会将其用于客户端

context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(10)); 

以及服务器端,因为您使用的是 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);
}

Old, question but the answer didn't really mentioned the server-side handling.

As in the winning answer, I would use this for the client side:

context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(10)); 

and for the server side, since you are using a ashx instead of a web page, I'm assuming that you are directly writing the output to the Context.Response.

In that case you could use something like this (in this case I want to save the response based on parameter "q", and Im using a sliding window expiration)

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);
}
眼角的笑意。 2024-08-02 04:36:14

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

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

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

在 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;
        }
    }
}

I used the following with success and thought it worthwhile to post here .

Manually controlling the ASP.NET page output cache

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

Setting cache options in Handler.ashx files

First, you can use HTTP handlers
in ASP.NET for a faster way to server
dynamic content than Web Form pages.
Handler.ashx is the default name for
an ASP.NET generic handler. You need
to use the HttpContext parameter and
access the Response that way.

Sample code excerpted:

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

C# to cache response for 1 hour

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;
        }
    }
}
过去的过去 2024-08-02 04:36:14

使用 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”中监视缓存。

The solution with the OutputCachedPage works fine, however at a price of the performance, since you need to instantiate an object derived from the System.Web.UI.Page base class.

A simple solution would be to use the Response.Cache.SetCacheability, as suggested by some of the above answers. However for the response to be cached at the server (inside Output Cache) one needs to use HttpCacheability.Server, and set a VaryByParams or VaryByHeaders (note that when using VaryByHeaders URL can't contain a query string, since the cache will be skipped).

Here's a simple example (based on 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;
        }
    }
}

Hint: you monitor the caching in the Performance Counters "ASP.NET Applications__Total__\Output Cache Total".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文