如何在控制台应用程序中使用System.Web.Caching.Cache?

29

背景: .Net 3.5, C#
我想在我的控制台应用程序中使用缓存机制。
为了避免重复造轮子,我想使用 System.Web.Caching.Cache (这是最终决定,不能使用其他缓存框架,请不要问为什么)。
然而,看起来 System.Web.Caching.Cache 只能在有效的HTTP上下文中运行。我的非常简单的代码片段如下:

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: 对象引用未设置为对象的实例。
   at System.Web.Caching.Cache.Insert(String key, Object value)
   at MyClass.RunSnippet()

显然,在这里我做错了什么。有任何想法吗?


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

6个回答

57

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


28

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

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


3
非常有用!我将在我的 Web 应用程序中切换呼叫以使用这种新方法。现在,这些方法可以进行单元测试,而无需定义 HttpContext.Cache。 :) - ClearCloud8

9
如果您不想重复造轮子,只需使用缓存应用程序块。如果您仍然想使用ASP.NET缓存,请参见此处。但是我相信这仅适用于.NET 2.0及以上版本。在.NET 1中无法在ASP.NET之外使用缓存。

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

Cache类不适用于ASP.NET应用程序之外。它是为了在ASP.NET中提供Web应用程序缓存而设计和测试的。在其他类型的应用程序(如控制台应用程序或Windows Forms应用程序)中,ASP.NET缓存可能无法正常工作。

对于非常轻量级的解决方案,您可以使用字典对象,无需担心过期等问题。


@Ron- 这是一个 Stackoverflow 的 bug。这是相同链接的 TinyUrl- http://tinyurl.com/ms35eu。 - RichardOD

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;

1
这很不规范,但当我有一个原型与依赖HttpContext.Current.Cache的外部dll集成时,它确实非常有用,我只需要让它工作。我在这里找到了一个更短的版本:http://caioproiete.net/en/fake-mock-httpcontext-without-any-special-mocking-framework/ - bygrace

1

尝试

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


1

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

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

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


1
“唯一设置的方式是通过内部方法”不正确,_cacheInternal是由静态属性访问器HttpRuntime.Cache设置的。然而,我对MSDN为什么建议在非Web应用程序中不使用ASP.NET Cache更感兴趣。我有使用它的代码(其创建日期早于此警告的存在),它似乎可以正常工作。 - Joe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接