Fody - кэширование методов

Я впервые использую кэш метода Fody (https://github.com/Dresel/MethodCache). . Я, вероятно, делаю что-то не так, потому что следующий код не работает:

static void Main()
{
  Console.WriteLine("Begin calc 1...");
  var v = calc(5);
  Console.WriteLine("Begin calc 2..."); //it last the same as the first function call
  v = calc(5);
  Console.WriteLine("end calc 2...");
}

 [Cache]
 static int calc(int b)
 {
   Thread.Sleep(5000);
   return b + 5;
 }

Что я должен использовать, что делает следующее: первый вызов: аргументы кэширования как ключи и возвращаемое значение как значение. любой другой вызов: if cache[arg1, arg2,...] существует возврат значения кеша без завершения функции? (с использованием атрибута кеша)


person dajuric    schedule 18.08.2013    source источник
comment
Почему второй вызов функции не будет длиться так же, как первый вызов функции? Вы просто спите в потоке, там нет кэшированных операций.   -  person Tarec    schedule 19.08.2013
comment
Хорошо, что я должен использовать, чтобы сделать следующее: первый вызов: кешировать аргументы как ключи и возвращать значение как значение. любой другой вызов: если cache[arg1, arg2,...] существует, вернуть значение кеша без завершения функции?   -  person dajuric    schedule 19.08.2013
comment
Насколько я понимаю, если функция кешируется, она не должна выполняться, а ее значение должно возвращаться из кеша. Я не понимаю, почему Thread.Sleep(..) не подходит?   -  person dajuric    schedule 20.08.2013


Ответы (1)


Как я уже говорил в вашей проблеме с github, кэширование статических методов было добавлено в 1.3.1.

Поскольку MethodCache.Fody разработан, вы также должны добавить в свой класс Cache Getter, который содержит методы, которые должны кэшироваться, и реализовать Cache. Вы можете запрограммировать свой собственный кэш или использовать адаптер для существующих решений кэша (см. документацию по https://github.com/Dresel/MethodCache).

Минимальный код для вашего примера (с базовой реализацией кэша словаря) будет выглядеть так:

namespace ConsoleApplication
{
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using MethodCache.Attributes;

    public class Program
    {
        private static DictionaryCache Cache { get; set; } 

        [Cache]
        private static int Calc(int b)
        {
            Thread.Sleep(5000);
            return b + 5;
        }

        private static void Main(string[] args)
        {
            Cache = new DictionaryCache();

            Console.WriteLine("Begin calc 1...");
            var v = Calc(5);

            // Will return the cached value
            Console.WriteLine("Begin calc 2...");
            v = Calc(5);

            Console.WriteLine("end calc 2...");
        }
    }

    public class DictionaryCache
    {
        public DictionaryCache()
        {
            Storage = new Dictionary<string, object>();
        }

        private Dictionary<string, object> Storage { get; set; }

        // Note: The methods Contains, Retrieve, Store must exactly look like the following:

        public bool Contains(string key)
        {
            return Storage.ContainsKey(key);
        }

        public T Retrieve<T>(string key)
        {
            return (T)Storage[key];
        }

        public void Store(string key, object data)
        {
            Storage[key] = data;
        }
    }
}

Однако более сложное решение будет использовать класс службы с интерфейсом ICache Getter и инъекцией кэша конструктором. ICache может обернуть любые существующие решения для кэширования.

person Dresel    schedule 24.09.2013