Как я могу использовать System.Web.Caching.Cache в консольном приложении? - PullRequest
29 голосов
/ 24 июня 2009

Контекст: .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);
}

и результат:

cannot insert to cache, exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Web.Caching.Cache.Insert(String key, Object value)
   at MyClass.RunSnippet()

Так что, очевидно, я здесь что-то не так делаю. Есть идеи?


Обновление : +1 для большинства ответов, правильное использование - получение кэша статическими методами, а именно HttpRuntime.Cache и HttpContext.Current.Cache. Спасибо всем!

Ответы [ 6 ]

56 голосов
/ 24 июня 2009

В документации к конструктору Cache говорится, что это только для внутреннего использования. Чтобы получить объект Cache, вызовите HttpRuntime.Cache, а не создавайте экземпляр с помощью конструктора.

28 голосов
/ 05 мая 2010

Хотя OP указывал v3.5, вопрос задавался до выпуска v4. Чтобы помочь любому, кто найдет этот вопрос и , жить с зависимостью v4, группа разработчиков создала новый кэш общего назначения для этого типа сценария. Он находится в пространстве имен System.Runtime.Caching: http://msdn.microsoft.com/en-us/library/dd997357%28v=VS.100%29.aspx

Статическая ссылка на экземпляр кэша по умолчанию: MemoryCache.Default

9 голосов
/ 24 июня 2009

Просто используйте Блок приложения кэширования , если вы не хотите изобретать велосипед. Если вы все еще хотите использовать кеш ASP.NET - , см. Здесь . Я уверен, что это работает только с .NET 2.0 и выше, хотя. Просто невозможно было использовать кеш вне ASP.NET в .NET 1.

На странице MSDN также есть большое предупреждение о документации кеша:

Класс Cache не предназначен для использовать вне приложений ASP.NET. Он был разработан и испытан для использования в ASP.NET для обеспечения кэширования для Web Приложения. В других типах приложения, такие как консоль приложения или Windows Forms приложения, кэширование ASP.NET может не работает правильно.

Для очень легкого решения, где вам не нужно беспокоиться об истечении срока действия и т. Д., Тогда достаточно словарного объекта.

4 голосов
/ 02 февраля 2010

Я закончил на этой странице, удивляясь тому же. Вот что я делаю (что мне не нравится, но, кажется, работает отлично):

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 голос
/ 24 июня 2009

Класс System.Web.Caching.Cache полагается на то, что его член "_cacheInternal" установлен объектом HttpRuntime.

Чтобы использовать классы System.Web.Caching, вам нужно создать объект HttpRuntime и настроить свойство HttpRuntime.Cache. Вы бы эффективно подражали IIS.

Вам лучше использовать другие инфраструктуры кэширования, такие как:

1 голос
/ 24 июня 2009

Попробуйте

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

...