【问题标题】:Why is my Lazy<T> re-initializing every time I call Value?为什么每次调用 Value 时我的 Lazy<T> 都会重新初始化?
【发布时间】:2018-06-19 01:24:54
【问题描述】:

我有一个控制器成员

    private Lazy<MyCache> loadedComponentCache = new Lazy<MyCache>(() =>
    {
        MyCache instance = MyCacheb.Instance;
        instance.LoadStuffAsync().Wait();
        return instance;
    }, LazyThreadSafetyMode.PublicationOnly);

我用来延迟调用长时间运行的方法LoadAsync(),只有在用户进入页面后点击某个 API 端点时才需要调用该方法。

    [HttpGet]
    public ActionResult GetStuff()
    {
        var results = from component in loadedComponentCache.Value.All()
                      // ... 
    }

知道为什么每次命中 API 端点时都会重新加载吗?我的理解是,我的控制器实例仅在用户访问页面时创建,因此每个访问页面的用户每次 API 调用只会点击一次。

【问题讨论】:

  • 为每个请求创建一个新的控制器实例。因此,您的 Lazy 会为每个请求有效地重新创建。
  • @zaitsman 谢谢。如何让它在每次页面访问时初始化一次?
  • “每页访问一次”是什么意思?每个请求都是一个page visit。所以你正在这样做......
  • 可能@Questionaire 使用“访问”作为“会话”的意思。在这种情况下,您需要添加一个(惰性)MyCache 实例作为 Session 项目
  • 你有一个无状态的应用程序,如果你不为每个请求初始化它,你怎么能使用loadedComponentCache 。如果您只想在整个应用程序生命周期中初始化一次,可以将其设为单例或静态。

标签: c# asp.net .net asp.net-mvc lazy-evaluation


【解决方案1】:

您可以将loadedComponentCache 设为静态,但这并不理想。如果您使用的是 IoC 容器,则可以将其注册为单例。尽管可能,但通常应避免使用这些长寿命的物体。

如果你真的需要这种长期存在的缓存,那么你可能应该考虑使用像 Redis 这样的东西,它是为这种场景设计和优化的,并且可以分布在多个节点上。 https://redis.io/topics/introduction

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多