ASP.NET:保存 WebConfigurationManager 时 HttpRuntime.Cache 被刷新——这是一个错误吗?

发布于 2024-09-28 04:32:07 字数 2154 浏览 0 评论 0原文

最近,我一直在尝试使用 HttpRuntime.Cache 缓存对象,我通常的印象是,如果我向缓存“添加”一些内容,如下所示:

HttpRuntime.Cache.Insert("Test", "This is a test!", null, 
     Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, 
     CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(FileChanged));

“NotRemovable”和“NoExpiration”标志将在应用程序运行期间将对象保留在内存中。但发现在某些页面请求结束时,HttpRuntime.Cache 将完全为空!

跟踪并在我的回调“FileChanged”中设置断点,我可以看到确实有东西正在“删除”我的对象(以及缓存中的所有其他对象),但我无法弄清楚为什么。所以最终,我开始禁用我认为可能影响该子系统的其他功能。

最终,我注释掉了这一行:

WebConfigurationManager.OpenWebConfiguration("~").Save;

我主要是从 AppSettings 区域中的“web.config”检索数据,但偶尔会写回 AppSettings 并使用上述命令保存更改。我从阅读中知道“web.config”已被缓存,但是将我的更改保存回它不应该刷新所有 HttpRuntime.Cache,对吧?

这是一个错误吗?或者这两个缓存是否以某种方式链接在一起,我应该知道?

编辑:

好吧,如果有人想在自己的机器上尝试这个,我已经使这个超级可重现。 (我正在运行 VS2008 Pro w/ MVC2,目标是 .NET 3.5)只需启动一个新的 MVC2 项目,并将以下内容粘贴到 HomeController 中,覆盖已有的内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Configuration;
using System.Configuration;

namespace BackButtonTest.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        private string MESSAGE = "Message";
        public ActionResult Index()
        {
            ViewData[MESSAGE] = HttpRuntime.Cache.Get(MESSAGE);
            Configuration Config = WebConfigurationManager.OpenWebConfiguration("~");
            Config.AppSettings.Settings.Add("SomeKey", "SomeValue");
            Config.Save();
            return View();
        }

        public ActionResult About()
        {
            HttpRuntime.Cache[MESSAGE] = "This is pulled from the HttpRuntime.Cache";
            return View();
        }
    }
}

然后按照以下步骤

  1. 操作 :应用程序处于调试模式。
  2. 单击“关于”链接。这会将字符串加载到缓存中。
  3. 单击“主页”链接。字符串从缓存中取出并保存在 ViewMessage 字典中。一些键/值对被写入 web.config 并保存。缓存中的字符串应出现在主页上。
  4. 再次单击“主页”链接。字符串应该从缓存中提取,但事实并非如此。
  5. 停止程序。注释掉以“Config”开头的 3 行。重新启动程序。
  6. 再次尝试步骤 1 至 4。请注意 HttpRuntime.Cache 尚未清空。

很奇怪吧?

Recently, I've been experimenting with caching objects with HttpRuntime.Cache and I was generally under the impression that if I "added" something to the cache like this:

HttpRuntime.Cache.Insert("Test", "This is a test!", null, 
     Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, 
     CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(FileChanged));

that the "NotRemovable" and "NoExpiration" flags would keep the object in-memory for the duration of the application. But was finding that at the end of certain page requests, the HttpRuntime.Cache would be completely empty!

Tracing thru and setting a breakpoint inside my Callback "FileChanged" I could see that indeed something was "removing" my object (and every other object in the cache), but I couldn't figure out why. So eventually, I started disabling other things that I thought might affect this subsystem.

Eventually, I commented out the line:

WebConfigurationManager.OpenWebConfiguration("~").Save;

I had been mostly retrieving data from "web.config" in the AppSettings region, but occasionally writing back to AppSettings and saving the changes using the above command. I knew from reading that the "web.config" is cached, but saving my changes back to it shouldn't flush all of HttpRuntime.Cache, right?

Is this a bug? Or are the two caches somehow linked in a way that I should be made aware of?

EDIT:

Ok, I've made this super reproducible if anyone wants to try this on their own machine. (I'm running VS2008 Pro w/ MVC2 targeting .NET 3.5) Just start up a new MVC2 project and paste the following into the HomeController over whatever is already there:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Configuration;
using System.Configuration;

namespace BackButtonTest.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        private string MESSAGE = "Message";
        public ActionResult Index()
        {
            ViewData[MESSAGE] = HttpRuntime.Cache.Get(MESSAGE);
            Configuration Config = WebConfigurationManager.OpenWebConfiguration("~");
            Config.AppSettings.Settings.Add("SomeKey", "SomeValue");
            Config.Save();
            return View();
        }

        public ActionResult About()
        {
            HttpRuntime.Cache[MESSAGE] = "This is pulled from the HttpRuntime.Cache";
            return View();
        }
    }
}

Then follow these steps:

  1. Start-up the app in debug mode.
  2. Click on the "About" link. This loads a string into the Cache.
  3. Click on the "Home" link. String is pulled from the Cache and stuck in ViewMessage dictionary. Some key/value pair is written to web.config and saved. String from cache should appear on the Home page.
  4. Click on the "Home" link again. String should be pulled from the cache, but it's not.
  5. Stop program. Comment out the 3 lines that start with "Config". Restart the program.
  6. Try steps 1 thru 4 again. Notice how the HttpRuntime.Cache has not been emptied.

Weird, huh?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寻找一个思念的角度 2024-10-05 04:32:07

写入 web.config 将强制应用程序重新启动,并且很可能清空缓存、进程内会话状态等事件将会发生。尝试在 global.asax Application_End 中写下一些日志(或任何方法的名称:))

Writing to your web.config will force the application to restart, and, most likely, events for emptying the cache, in-proc sessionstate etc. will go off. Try and write down some log in global.asax Application_End (or whatever the name of the method is :) )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文