一个个页面打开的时候正常,访问量大的时候缓存就错乱了,找不到解决的方法,参照MVC里的OutputCache源代码写的
using System; using System.Collections.Generic; using System.IO; using System.Web; using System.Web.Mvc; using System.Reflection; using Newtonsoft.Json; using System.Text; using System.Configuration; using Benz.Core.Injection; using Autofac; using System.Web.UI; using Benz.Core.Cache; using Benz.Core.Helper; using Benz.Core.Log; using System.Globalization; namespace Benz.Core.OutputCache { public class ResultCachingAttribute : ActionFilterAttribute, IExceptionFilter { private readonly static string siteUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["HostMechine"].ToString(); private readonly static long cacheMaxTime = long.Parse(System.Web.Configuration.WebConfigurationManager.AppSettings["cacheTime"].ToString()); private ICacheManager cacheMgr = ContainerManager.Engine.Container.Resolve<ICacheManager>(); private MemoryCacheManager localCache = new MemoryCacheManager(); private MessageHelper<string> message = new MessageHelper<string>(); private static string UA = "CacheRefreshService"; private static object _actionFilterFinishCallbackKey = new object(); private ILoggerService log = new LoggerService(); public int Duration { get; set; } public ResultCachingAttribute() { } private string CacheKey; private string userArgent; /// <summary> /// 在执行操作方法之前调用。 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(ActionExecutingContext filterContext) { this.CacheKey = CreateKey(filterContext); this.userArgent = filterContext.RequestContext.HttpContext.Request.UserAgent.Trim().ToLower(); bool needRun = false; if (!userArgent.Equals(UA.Trim(), StringComparison.OrdinalIgnoreCase)) { if (localCache.HasKey(this.CacheKey)) { string html = localCache.Get<string>(this.CacheKey); if (html.Length < 50) return; filterContext.Result = new ContentResult { Content = html }; } else { if (cacheMgr.HasKey(this.CacheKey)) { string html = cacheMgr.Get<string>(this.CacheKey); if (html.Length < 50) return; message.SendMessage(filterContext.HttpContext.Request.Url.ToString()); filterContext.Result = new ContentResult { Content = html }; } else needRun = true; } } else needRun = true; if (needRun) { StringWriter cachingWriter = new StringWriter(CultureInfo.InvariantCulture); TextWriter originalWriter = filterContext.HttpContext.Response.Output; filterContext.HttpContext.Response.Output = cachingWriter; SetActionFilterFinishCallback(filterContext, wasException => { filterContext.HttpContext.Response.Output = originalWriter; string capturedText = cachingWriter.ToString(); filterContext.HttpContext.Response.Write(capturedText); //if (!wasException) //{ cacheMgr.Set(this.CacheKey, capturedText, cacheMaxTime); localCache.Set(this.CacheKey, capturedText, Duration); //} }); } } public override void OnResultExecuted(ResultExecutedContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } CompleteAction(filterContext, wasException: filterContext.Exception != null); } private static void SetActionFilterFinishCallback(ControllerContext controllerContext, Action<bool> callback) { controllerContext.HttpContext.Items[_actionFilterFinishCallbackKey] = callback; } private static Action<bool> GetActionFilterFinishCallback(ControllerContext controllerContext) { return controllerContext.HttpContext.Items[_actionFilterFinishCallbackKey] as Action<bool>; } private static void ClearActionFilterFinishCallback(ControllerContext controllerContext) { controllerContext.HttpContext.Items.Remove(_actionFilterFinishCallbackKey); } private static void CompleteAction(ControllerContext filterContext, bool wasException) { Action<bool> callback = GetActionFilterFinishCallback(filterContext); if (callback != null) { ClearActionFilterFinishCallback(filterContext); callback(wasException); } } /// <summary> /// 创建缓存Key /// </summary> /// <param name="filterContext"></param> /// <returns></returns> private static string CreateKey(ControllerContext filterContext) { HttpRequestBase bases = (HttpRequestBase)filterContext.HttpContext.Request; string port = ":"+bases.Url.Port.ToString(); return bases.Url.ToString() .ToLower() .Replace("://", "__") .Replace(siteUrl, "host") .Replace(port, "") .Replace("/", "_") .Replace(".", "_"); } public void OnException(ExceptionContext filterContext) { if (filterContext == null) throw new ArgumentNullException("filterContext"); CompleteAction(filterContext, wasException: true); } } }
缓存错乱时, string html = cacheMgr.Get<string>(this.CacheKey); 读出来的值是正常的码?
localCache和cacheMgr里读出来的值都不相同
localCache和cacheMgr里缓存的内容都是错误的
@凬月: 试试把CacheKey定义为局部变量
@dudu: 晕~~~~~正确了。。。居然是这里的问题
我再验证一下,没问题就结贴:)