首页 新闻 会员 周边

MVC自定义缓存,高并发时缓存内容错乱

0
悬赏园豆:200 [已关闭问题] 关闭于 2015-05-12 13:53

一个个页面打开的时候正常,访问量大的时候缓存就错乱了,找解决的方法,各位高手帮忙看看吧,很急

 

 

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 Autofac;
using System.Web.UI;
using System.Globalization;

namespace 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 _acti /> 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 { C /> }
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 { C /> }
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 (filterC /> {
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 (filterC /> throw new ArgumentNullException("filterContext");

CompleteAction(filterContext, wasException: true);
}
}
}

凬月的主页 凬月 | 初学一级 | 园豆:21
提问于:2015-05-12 13:46
< >
分享
所有回答(1)
0

CreateKey()没有考虑查询参数的不同,是不是与这个问题有关

dudu | 园豆:31007 (高人七级) | 2015-05-12 13:55

createkey()获得key值是不同的,在redis里可以看到

支持(0) 反对(0) 凬月 | 园豆:21 (初学一级) | 2015-05-12 13:57

@凬月: 缓存读取 cacheMgr.Get<string>(this.CacheKey) 确认没问题吗?

支持(0) 反对(0) dudu | 园豆:31007 (高人七级) | 2015-05-12 14:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册