編輯:對於每個請求,創建一個新的控制器實例。但是,對於Attribute類,這不是真的。一旦它們被創建,它就被用於多個請求。我希望它有幫助。緩存WebAPI 2
我寫我自己的WebAPI(使用最新版本的WebAPI和.NET Framework)的緩存行爲過濾器。我知道CacheCow & this。不過,我想我的反正。
然而,有一些問題,我的代碼,因爲當我在現場服務器項目中使用它我不明白exepected輸出。在本地機器上一切正常。
我用下面的代碼在我的博客RSS生成和我緩存數據,爲每個類別。有大約5類(食品,科技,個人等)。
問題:當我導航說api/GetTech時,它會返回我個人博客類別中的RSS源項目。當我瀏覽說API/GetPersonal,它返回我的API /食品
我無法找到問題的根源,但我認爲這是由於使用了靜態方法/變量。我再一次檢查了我的_cachekey
對我的博客的每個類別都有獨特的價值。
可有人指出,此代碼ESP任何問題,當我們說每分鐘300個請求?
public class WebApiOutputCacheAttribute : ActionFilterAttribute
{
// Cache timespan
private readonly int _timespan;
// cache key
private string _cachekey;
// cache repository
private static readonly MemoryCache _webApiCache = MemoryCache.Default;
/// <summary>
/// Initializes a new instance of the <see cref="WebApiOutputCacheAttribute"/> class.
/// </summary>
/// <param name="timespan">The timespan in seconds.</param>
public WebApiOutputCacheAttribute(int timespan)
{
_timespan = timespan;
}
public override void OnActionExecuting(HttpActionContext ac)
{
if (ac != null)
{
_cachekey = ac.Request.RequestUri.PathAndQuery.ToUpperInvariant();
if (!_webApiCache.Contains(_cachekey)) return;
var val = (string)_webApiCache.Get(_cachekey);
if (val == null) return;
ac.Response = ac.Request.CreateResponse();
ac.Response.Content = new StringContent(val);
var contenttype = (MediaTypeHeaderValue)_webApiCache.Get("response-ct") ?? new MediaTypeHeaderValue("application/rss+xml");
ac.Response.Content.Headers.ContentType = contenttype;
}
else
{
throw new ArgumentNullException("ac");
}
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (_webApiCache.Contains(_cachekey)) return;
var body = actionExecutedContext.Response.Content.ReadAsStringAsync().Result;
if (actionExecutedContext.Response.StatusCode == HttpStatusCode.OK)
{
lock (WebApiCache)
{
_wbApiCache.Add(_cachekey, body, DateTime.Now.AddSeconds(_timespan));
_webApiCache.Add("response-ct", actionExecutedContext.Response.Content.Headers.ContentType, DateTimeOffset.UtcNow.AddSeconds(_timespan));
}
}
}
}
「我認爲當一個類有私有變量&說我們有2個類的實例時,每個類都有它自己的內存和自己的私有變量。」 - 是的,我誤導了你。但是,在這種情況下你並沒有處理2個實例。您正在處理2個或更多不同請求線程正在使用的1個實例。 – danludwig 2014-11-06 14:15:39
是的。我認爲我不需要鎖定代碼,因爲MemoryCache是線程安全的。我的理解是正確的嗎? – NoobDeveloper 2014-11-06 16:29:47
將值添加到緩存時,「鎖定」是不必要的,只會減慢使用該屬性的請求,但可能不會太多。 – danludwig 2014-11-07 14:03:03