MethodInfo.Invoke иногда возвращает ноль, а иногда возвращает значение - PullRequest
0 голосов
/ 21 августа 2009

Я работаю над приложением asp.net MVC.

У меня есть класс, который упаковывает репозиторий, который выбирает данные из БД, используя простое выражение linq. Я написал класс декоратора для добавления логики кэширования (используя блок приложения кэширования).

так как у меня есть несколько методов, которые я хочу декорировать, и логика для каждого из них одинакова (проверьте, существует ли в кэше, если не вызываете реальный геттер и сохраните в кэше), я написал что-то вроде этого: *

вспомогательный метод, который выполняет общую логику проверки, существует ли в кэше и т. Д.:

    public object CachedMethodCall(MethodInfo realMethod, params object[] realMethodParams)
    {
        object result = null;
        string cacheKey = CachingHelper.GenereateCacheKey(realMethod, realMethodParams);

        // check if cache contains key, if yes take data from cache, else invoke real service and cache it for future use.
        if (_CacheManager.Contains(cacheKey))
        {
            result = _CacheManager.GetData(cacheKey);
        }
        else
        {
            result = realMethod.Invoke(_RealService, realMethodParams);

            // TODO: currently cache expiration is set to 5 minutes. should be set according to the real data expiration setting.
            AbsoluteTime expirationTime = new AbsoluteTime(DateTime.Now.AddMinutes(5));
            _CacheManager.Add(cacheKey, result, CacheItemPriority.Normal, null, expirationTime);
        }

        return result;
    }

все это прекрасно работает и прекрасно. в каждом оформленном методе у меня есть следующий код:

StackTrace currentStack = new StackTrace();
string currentMethodName = currentStack.GetFrame(0).GetMethod().Name;
var result = (GeoArea)CachedMethodCall(_RealService.GetType().GetMethod(currentMethodName), someInputParam);
return result;

проблема в том, что иногда строка, в которой происходит realMethod.Invoke(...), возвращает ноль. Если я ставлю точку останова сразу после этого и затем возвращаю выполнение в эту строку, результат не равен нулю и данные выбираются из БД. все входные переменные верны, данные существуют в БД, второй прогон получает данные, так что же не так в первом прогоне?!

спасибо:)

1 Ответ

0 голосов
/ 21 августа 2009

Я думаю, что мне удалось решить эту проблему, обновив код следующим образом:

    public object CachedMethodCall(MethodInfo realMethod, params object[] realMethodParams)
    {
        string cacheKey = CachingHelper.GenereateCacheKey(realMethod, realMethodParams);

        object result = _CacheManager.GetData(cacheKey);

        if (result == null)
        {
            result = realMethod.Invoke(_RealService, BindingFlags.InvokeMethod, null, realMethodParams, CultureInfo.InvariantCulture);

            // TODO: currently cache expiration is set to 5 minutes. should be set according to the real data expiration setting.
            AbsoluteTime expirationTime = new AbsoluteTime(DateTime.Now.AddMinutes(5));
            _CacheManager.Add(cacheKey, result, CacheItemPriority.Normal, null, expirationTime);
        }

        return result;
    }

Я заметил, что предыдущий вызов _CacheManager.Contains иногда возвращал true, хотя кэш не содержал данные. Я подозреваю, что потоки вызывают проблемы, но я не уверен ...

...