在 Web 应用程序中缓存导航树



解释

导航树 (NT) 是从 API(不在我的控制范围内)加载的,它显示的节点是每种类型(类别、进程等)之一,并且每次有人转到我的搜索页面时都会完成加载过程(Search.cshtml)。请注意,我从头开始创建了 NT。它不是任何类型的插件。

出于优化目的,我需要缓存整个 NT(每个节点)。然后,当用户到达搜索页面时,将根据用户的权限快速加载和筛选缓存的 NT。

现在,我有加载所有节点并按用户过滤它们的方法,我还有一个名为partialNavigationTree(pNT) 的模型,它有 1 种擦除空文件夹的方法,以及 3 个像这样的列表List<NavTreeNode>,其中 NTN 也是一个模型,用于存储将节点呈现为搜索页面所需的一些信息。

因此,目标是拥有一个静态的、线程安全的 pNT 变量,该变量在 Web 应用初始化时加载,控制器的方法可以从中读取。我已经有一个特定的类可以保存这个名为static class TheHelper的变量。


我的计划

在类RouteConfig中,方法RegisterRoutes中,我会将代码从类加载静态变量CachedNavigationTree(CNTTheHelper),然后让显示搜索页面的控制器将 CNT 的内容复制到他的局部变量中,过滤每个节点列表中的节点,然后传递给视图该局部变量。这样,我在 Web 应用程序启动时获得 CNT,并在为每个用户加载 NT 时获得速度。


顾虑和问题

  1. 如何声明静态 CNT?当多个用户尝试同时读取它时,像这样清除它public static CachedNavigationTree { get; set; }会导致问题吗?这是保护 1class变量的线程安全方法吗?
  2. RouteConfig.RegisterRoutes是我找到的"最深"函数(最接近 Web 应用程序启动点),所以我将"应用程序启动时执行此操作"代码放在那里。有没有"更深"/更好的地方来放置这种代码?
  3. 由于 pNT 模型中的节点列表是List<T>的,我该如何复制这些列表?如果我们有 2 个列表,A 和 B,假设 A 已满,然后输入B = A;,那么 B 列表的项目将仅引用列表 A 中的项目,这意味着更改列表 Bs 项目也会更改列表 As 项目,反之亦然。这是对的吗?我应该担心我复制列表的方式,还是我上面所说的是错误的,我可以放心地说var localList = TheHelper.CachedNavigationTree;
  4. 这是我用我所拥有的知识想出的缓存方式。如果在 C#/MVC 中已经有一种预制的缓存类变量的方法,我不会感到惊讶。如果它存在,并且你知道它,请详细说明。

编辑

问题 3 是实际的 - 如何将完整列表复制到空列表,并再次从完整列表生成项目。因为在 C# 中,当您输入List<string> A = new ...; List<string> B = A;时,当您更改(假设)B 列表中的第一项时,该项也会在 A 列表中更改。因此,同一列表实际上只有 2 个名称,而不是 RAM 中的 2 个列表。希望这能解决问题3。另外,答案在这里。我很抱歉解释不好。

1)我认为使用MemoryCache来保存变量会更明智,这仍然可以在整个应用程序中访问,但是是保存数据的特定设备(也是它的设计目的)。使用它也非常简单。您可以在System.Web.Caching中找到Cache适用于较旧的 3.5 版之前的应用,MemoryCacheSystem.Runtime.Caching适用于较新的应用)。 这也将为您提供一些额外的控件,例如过期,可配置的大小限制,轮询间隔等。CacheMemoryCache之间的主要区别在于,较新的MemoryCache也设计为在不直接 ASP.NET 的系统下工作

2) 您可能希望查看 MSDN 上的应用程序生命周期详细信息。更多的处理程序和钩子专门设计用于global.asax文件中的此类目的 - 无论是应用程序首次启动时(Application_Start)还是页面请求进入时(Application_BeginRequest)。您可以在Application_Start中构建缓存,然后让它调用过期回调,以便在一段时间内发生变化时重新计算(并替换变量),而无需每次进行更改时都重新启动应用。

3)对不起,我不太明白你在这里的要求。

4) 个人 ID 切换到为此系统使用 MemoryCache 并在那里缓存您的数据。如果您只是向请求导航树的用户发送静态 API 值,那么我也会考虑使用Vary系统实现响应缓存

最新更新