0

私は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(...)null を返す場合があることです。直後にブレークポイントを置いてその行に実行を戻すと、結果は null ではなく、DB からデータがフェッチされます。すべての入力変数が正しく、データが DB に存在し、2 回目の実行でデータが取得されるため、最初の実行で何が問題になるのでしょうか?!

ありがとう :)

4

1 に答える 1

0

次のようにコードを更新することで、この問題を解決できたと思います。

    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が返されることがあることに気付きました。スレッドが問題を引き起こしているのではないかと思いますが、よくわかりません...

于 2009-08-21T12:28:39.110 に答える