Asp.Net 服务器端输出缓存在每次请求时都会被命中 (HttpHandler)
Asp.Net Server-side Output Cache gets hit every request (HttpHandler)
我在下面有一段非常简单的代码。
我尝试了几种方法,但我不明白为什么服务器端输出缓存在 http://localhost 时不工作。下面是 'cache settings' 的最后一次尝试,以便 不会 在调试输出窗格中看到 HIT。
快把我逼疯了!我该如何防止 HIT...?!当我打开开发人员工具并选中禁用缓存时,我期待缓存的服务器端副本,但在调试输出窗格中看不到 HIT。
我在 Windows 8,但即使在另一个 Windows 版本(/IIS 版本)上,我也无法想象最终的代码会有所不同。
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Web;
namespace WebApplication1
{
/// <summary>
/// Summary description for MyHandler
/// </summary>
public class MyHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
Debug.WriteLine("HIT"+DateTime.Now.ToLongTimeString());
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(5));
context.Response.Cache.SetCacheability(HttpCacheability.Server);
context.Response.Cache.SetValidUntilExpires(true);
context.Response.Cache.SetOmitVaryStar(true);
context.Response.Cache.VaryByParams["none"] = true;
context.Response.Cache.SetMaxAge(new TimeSpan(0, 5, 0));
// Just here for testing purposes
const string url = "http://otherserver/image.png";
using (var client = new HttpClient())
{
var task = client.GetStreamAsync(url);
task.Wait();
task.Result.CopyTo(context.Response.OutputStream);
context.ApplicationInstance.CompleteRequest();
}
}
public bool IsReusable
{
get { return true; }
}
}
}
原来是 ApplicationInstance.CompleteRequest()
造成了我的痛苦。根据MSDN它:
Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
如您所见,处理程序正在中间某处执行,在调用 ApplicationInstance.CompleteRequest()
之后它会跳过所有内容并直接转到发送请求(或内部 CompleteRequest()
)。
发生这种情况时,它还会跳过 "Update cache" 事件。这是请求缓存更新的地方; Server-side 输出缓存项将添加到哪里...
所以,当您认为自己已经完成 HttpHandler
时,请注意 ApplicationInstance.CompleteRequest()
做了什么!
另一个有趣的读物:https://weblog.west-wind.com/posts/2009/May/21/Dont-use-ResponseEnd-with-OutputCache
快乐缓存!
我在下面有一段非常简单的代码。
我尝试了几种方法,但我不明白为什么服务器端输出缓存在 http://localhost 时不工作。下面是 'cache settings' 的最后一次尝试,以便 不会 在调试输出窗格中看到 HIT。
快把我逼疯了!我该如何防止 HIT...?!当我打开开发人员工具并选中禁用缓存时,我期待缓存的服务器端副本,但在调试输出窗格中看不到 HIT。
我在 Windows 8,但即使在另一个 Windows 版本(/IIS 版本)上,我也无法想象最终的代码会有所不同。
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Web;
namespace WebApplication1
{
/// <summary>
/// Summary description for MyHandler
/// </summary>
public class MyHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
Debug.WriteLine("HIT"+DateTime.Now.ToLongTimeString());
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(5));
context.Response.Cache.SetCacheability(HttpCacheability.Server);
context.Response.Cache.SetValidUntilExpires(true);
context.Response.Cache.SetOmitVaryStar(true);
context.Response.Cache.VaryByParams["none"] = true;
context.Response.Cache.SetMaxAge(new TimeSpan(0, 5, 0));
// Just here for testing purposes
const string url = "http://otherserver/image.png";
using (var client = new HttpClient())
{
var task = client.GetStreamAsync(url);
task.Wait();
task.Result.CopyTo(context.Response.OutputStream);
context.ApplicationInstance.CompleteRequest();
}
}
public bool IsReusable
{
get { return true; }
}
}
}
原来是 ApplicationInstance.CompleteRequest()
造成了我的痛苦。根据MSDN它:
Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
如您所见,处理程序正在中间某处执行,在调用 ApplicationInstance.CompleteRequest()
之后它会跳过所有内容并直接转到发送请求(或内部 CompleteRequest()
)。
发生这种情况时,它还会跳过 "Update cache" 事件。这是请求缓存更新的地方; Server-side 输出缓存项将添加到哪里...
所以,当您认为自己已经完成 HttpHandler
时,请注意 ApplicationInstance.CompleteRequest()
做了什么!
另一个有趣的读物:https://weblog.west-wind.com/posts/2009/May/21/Dont-use-ResponseEnd-with-OutputCache
快乐缓存!