在using语句之外调用AggressivelyCacheFor(duration)有什么影响?

时间:2012-11-09 17:21:08

标签: c# asp.net-web-api ravendb

我正在尝试在WebApi应用程序中启用RavenDB Aggressive Caching,以便在更大的应用程序中启用单个操作方法。

为了实现这一点,我采用了创建动作过滤器属性的路径,该属性获取IDocumentSession,并且在OnActionExecuting中调用方法以启用激进缓存15分钟。然后,在OnActionexecuted中,我在同一会话中调用DisableAggressiveCaching()

简而言之,这导致了一些相当奇怪的行为。在调用了使用Aggressive Caching的action方法之后,对其他操作方法的后续请求(无论如何都不依赖于缓存(它们发出完全不同的请求))最终获得IDocumentSession AggressiveCacheDuration所在的IDocumentStore 1}}是15分钟。发生这种情况的频率似乎与之前调用缓存的操作方法的次数成正比。我应该补充一点,我正在使用StructureMap for DI,使用IDocumentSession单例,并注入一个HttpContextScoped var documentStore = new DocumentStore {ConnectionStringName = "RavenDB"}; documentStore.Initialize(); For<IDocumentStore>().Singleton().Use(documentStore); For<IDocumentSession>().HttpContextScoped().Use(x => { var store = x.GetInstance<IDocumentStore>(); var session = store.OpenSession(); return session; }); 。我已经确认每个请求都会注入一个新的IDocumentSession,但其中一些已经启用了缓存。

有些代码可以进一步详细说明......

IoC - RavenRegistry

public class AggressivelyCacheAttribute : ActionFilterAttribute
{
    private IDocumentSession _documentSession;

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        base.OnActionExecuting(actionContext);

        _documentSession = actionContext.Request.GetDependencyScope()
            .GetService(typeof(IDocumentSession)) as IDocumentSession;

        _documentSession.Advanced.DocumentStore
            .AggressivelyCacheFor(TimeSpan.FromMinutes(15));
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
        _documentSession.Advanced.DocumentStore.DisableAggressiveCaching();
    }
}

AggressivelyCacheAttribute

IDocumentSession

然后在管道中使用相同的IDocumentSession来查询数据库,其结果被缓存。

在后续请求中,对于不存在该属性的方法,注入的{{1}}将缓存设置为15分钟。为什么会这样?

我在网上看到的唯一例子是在using语句中使用缓存创建会话的地方。这是使用Aggressive Caching的唯一“安全”方式,还是可以做我正在尝试的事情?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:1)

根据Ayende's blogging platform code,您需要在过滤器类中添加引用:

private IDisposable _cachingHandle;

然后,当您进行缓存声明时,将结果分配给:

_cachingHandle  = _documentSession.Advanced.DocumentStore
    .AggressivelyCacheFor(TimeSpan.FromMinutes(15));

然后在你的执行中,

if(_cachingHandle != null)
    _cachingHandle.Dispose();

这应该可以阻止不必要的缓存。