シングルトン クラス内に、3 つのパラメーターを使用する汎用キャッシュ アクセス メソッドがあります。
- デリゲート (パラメーターのない void 戻り値の型)
- キャッシュ ラベル
- 同時キャッシュ設定を停止するように設計されたロック オブジェクト
下記参照:
protected delegate T GetDataMethod<T>();
protected override D GetCachedData<D>(GetDataMethod<D> dataAccessMethod, string cachelabel, object lockObject)
{
if (MemoryCache.Default[cachelabel] == null)
{
lock (lockObject)
{
//Inside the lock, test once again in case the cache object has been set already
if (MemoryCache.Default[cachelabel] == null)
{
umbraco.BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Debug, -10, cachelabel + " inside lock, cache empty");
D data = default(D);
try
{
data = dataAccessMethod();
}
catch (Exception ex)
{
//Logging
}
MemoryCache.Default.Add(cachelabel, data, GetCacheItemPolicy());
}
}
}
return (D)MemoryCache.Default[cachelabel];
}
キャッシュされたデータ コレクションごとに個別のロック オブジェクトがあり、静的な読み取り専用オブジェクトとして設定されています。ただし、それらをメソッドに渡すと、スコープはメソッド内にのみ存在するため、ロックは無関係になります。
周囲のクラスがシングルトンであることを考えると、ref で静的オブジェクトを渡すことができないため、「ref」を使用できません。ロック オブジェクトを非静的にするかどうかは問題になりますか? そうであれば、cacheLabel に基づく switch ステートメントを使用せずにそれを処理するより良い方法を誰かが推奨できますか?
編集:メソッドのフットプリントを明確にするために:
protected override D GetCachedData<D>(GetDataMethod<D> dataAccessMethod, string cachelabel, ref object lockObject)
ロック オブジェクトは静的であるため、機能しません。問題は本当に-シングルトン内で、ロックオブジェクトをスレッドセーフにするために静的である必要がありますか? (はい、スレッドセーフなシングルトンです)