【问题标题】:What is the effect of calling AggressivelyCacheFor(duration) outside of a using statement?在 using 语句之外调用 AggressivelyCacheFor(duration) 有什么影响?
【发布时间】:2012-11-10 13:34:47
【问题描述】:

我正在尝试在 WebApi 应用程序中启用 RavenDB 主动缓存,以便在较大的应用程序中实现单个操作方法。

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

简而言之,这导致了一些相当奇怪的行为。在调用使用积极缓存的操作方法之后,对其他操作方法的后续请求,无论如何都不依赖缓存(它们发出完全不同的请求),最终得到一个IDocumentSession,其中AggressiveCacheDuration 是15分钟。这种情况发生的频率似乎与之前调用缓存操作方法的次数成正比。我应该补充一点,我正在为 DI 使用 StructureMap,使用 IDocumentStore 单例,并注入 HttpContextScoped IDocumentSession。我已经确认每个请求都会注入一个新的 IDocumentSession,但其中一些已启用缓存。

一些代码可以尝试进一步阐述......

IoC - RavenRegistry

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;
});

积极缓存属性

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();
    }
}

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

在后续请求中,在属性不存在的方法上,注入的IDocumentSession 缓存设置为 15 分钟。为什么会这样?

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

【问题讨论】:

  • 我不知道这是否可行,但您是否尝试过在 Application_EndRequest 处理您的会话?或者只是禁用注册表中的缓存。

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


【解决方案1】:

基于Ayende's blogging platform code,你需要在你的过滤器类中有一个引用:

private IDisposable _cachingHandle;

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

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

然后在你的Executed中,

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

这应该会停止不需要的缓存。

【讨论】:

    猜你喜欢
    • 2011-10-05
    • 1970-01-01
    • 2019-09-20
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多