【问题标题】:How can I use System.Web.Caching.Cache in a Console application?如何在控制台应用程序中使用 System.Web.Caching.Cache?
【发布时间】:2010-11-05 11:30:52
【问题描述】:

上下文:.Net 3.5,C#
我想在我的控制台应用程序中使用缓存机制。
而不是重新发明轮子,我想使用System.Web.Caching.Cache(这是最终决定,我不能使用其他缓存框架,不要问为什么)。
但是,看起来 System.Web.Caching.Cache 应该只在有效的 HTTP 上下文中运行。我非常简单的 sn-p 看起来像这样:

using System;
using System.Web.Caching;
using System.Web;

Cache c = new Cache();

try
{
    c.Insert("a", 123);
}
catch (Exception ex)
{
    Console.WriteLine("cannot insert to cache, exception:");
    Console.WriteLine(ex);
}

结果是:

无法插入缓存,异常: System.NullReferenceException:对象引用未设置为对象的实例。 在 System.Web.Caching.Cache.Insert(字符串键,对象值) 在 MyClass.RunSnippet()

很明显,我在这里做错了。有什么想法吗?


更新:对大多数答案+1,通过静态方法获取缓存是正确的用法,即HttpRuntime.CacheHttpContext.Current.Cache。谢谢大家!

【问题讨论】:

    标签: .net caching console-application httpcontext


    【解决方案1】:

    Cache 构造函数的文档说它仅供内部使用。要获取您的 Cache 对象,请调用 HttpRuntime.Cache 而不是通过构造函数创建实例。

    【讨论】:

      【解决方案2】:

      虽然 OP 指定了 v3.5,但问题是在 v4 发布之前提出的。为了帮助发现这个问题的任何人并且可以忍受 v4 依赖项,框架团队为这种类型的场景创建了一个新的通用缓存。它在 System.Runtime.Caching 命名空间中: http://msdn.microsoft.com/en-us/library/dd997357%28v=VS.100%29.aspx

      默认缓存实例的静态引用是:MemoryCache.Default

      【讨论】:

      • 非常有用!我正在我的 webapp 中切换调用以使用这种新方法。现在可以对这些方法进行单元测试,而无需定义 HttpContext.Cache。 :)
      【解决方案3】:

      如果您不想重新发明轮子,只需使用Caching Application Block。如果您仍想使用 ASP.NET 缓存 - see here。我很确定这仅适用于 .NET 2.0 及更高版本。根本不可能在 .NET 1 中使用 ASP.NET 之外的缓存。

      MSDN 在缓存文档的页面上也有一个很好的警告:

      Cache 类不适用于 在 ASP.NET 应用程序之外使用。 它被设计和测试用于 ASP.NET 为 Web 提供缓存 应用程序。在其他类型 应用程序,例如控制台 应用程序或 Windows 窗体 应用程序,ASP.NET 缓存可能 不能正常工作。

      对于一个非常轻量级的解决方案,您不必担心过期等问题,那么字典对象就足够了。

      【讨论】:

      【解决方案4】:

      我在这个页面结束时想知道同样的事情。这就是我正在做的事情(我不喜欢,但似乎工作得很好):

      HttpContext context = HttpContext.Current;
      if (context == null)
      {
          HttpRequest request = new HttpRequest(string.Empty, "http://tempuri.org", string.Empty);
          HttpResponse response = new HttpResponse(new StreamWriter(new MemoryStream()));
          context = new HttpContext(request, response);
          HttpContext.Current = context;
      }
      this.cache = context.Cache;
      

      【讨论】:

      • 这太脏了,但是当我有一个与依赖于 HttpContext.Current.Cache 的外部 dll 集成的原型并且我只需要它工作时,它真的派上了用场。我在这里找到了一个较短的版本:caioproiete.net/en/…
      【解决方案5】:

      试试

      public class AspnetDataCache : IDataCache
      {
          private readonly Cache _cache;
      
          public AspnetDataCache(Cache cache)
          {
              _cache = cache;
          }
      
          public AspnetDataCache()
              : this(HttpRuntime.Cache)
          {
      
          }
          public void Put(string key, object obj, TimeSpan expireNext)
          {
              if (key == null || obj == null)
                  return;
              _cache.Insert(key, obj, null, DateTime.Now.Add(expireNext), TimeSpan.Zero);
          }
      
          public object Get(string key)
          {
              return _cache.Get(key);
          }
      
      

      【讨论】:

        【解决方案6】:

        System.Web.Caching.Cache 类依赖于由 HttpRuntime 对象设置其成员“_cacheInternal”。

        要使用 System.Web.Caching 类,您必须创建一个 HttpRuntime 对象并设置 HttpRuntime.Cache 属性。您实际上必须模拟 IIS。

        您最好使用其他缓存框架,例如:

        【讨论】:

        • “唯一的设置方法是通过内部方法” - 不正确,_cacheInternal 由静态属性访问器 HttpRuntime.Cache 设置。但是,我会对有关 MSDN 为何不建议在非 Web 应用程序中使用 ASP.NET 缓存的更多信息感兴趣。我有使用它的代码(可以追溯到此警告存在之前),并且它似乎可以正常工作。
        猜你喜欢
        • 2021-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-30
        • 2019-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多