У меня есть следующее расширение
Public Module CacheExtensions
Sub New()
End Sub
Private sync As New Object()
Public Const DefaultCacheExpiration As Integer = 1200 ''# 20 minutes
<Extension()>
Public Function GetOrStore(Of T)(ByVal cache As Cache, ByVal key As String, ByVal generator As Func(Of T)) As T
Return cache.GetOrStore(key, If(generator IsNot Nothing, generator(), Nothing), DefaultCacheExpiration)
End Function
<Extension()>
Public Function GetOrStore(Of T)(ByVal cache As Cache, ByVal key As String, ByVal generator As Func(Of T), ByVal expireInSeconds As Double) As T
Return cache.GetOrStore(key, If(generator IsNot Nothing, generator(), Nothing), expireInSeconds)
End Function
<Extension()>
Public Function GetOrStore(Of T)(ByVal cache As Cache, ByVal key As String, ByVal obj As T) As T
Return cache.GetOrStore(key, obj, DefaultCacheExpiration)
End Function
<Extension()>
Public Function GetOrStore(Of T)(ByVal cache As Cache, ByVal key As String, ByVal obj As T, ByVal expireInSeconds As Double) As T
Dim result = cache(key)
If result Is Nothing Then
SyncLock sync
If result Is Nothing Then
result = If(obj IsNot Nothing, obj, Nothing)
cache.Insert(key, result, Nothing, DateTime.Now.AddSeconds(expireInSeconds), cache.NoSlidingExpiration)
End If
End SyncLock
End If
Return DirectCast(result, T)
End Function
End Module
Здесь я использую расширение TagService для получения списка тегов
Public Function GetTagNames() As List(Of String) Implements Domain.ITagService.GetTags
''# We're not using a dynamic Cache key because the list of TagNames
''# will persist across all users in all regions.
Return HttpRuntime.Cache.GetOrStore(Of List(Of String))("TagNamesOnly",
Function() _TagRepository.Read().Select(Function(t) t.Name).OrderBy(Function(t) t).ToList())
End Function
Все этов значительной степени прямо вперед, за исключением случаев, когда я ставлю точку останова на _TagRepository.Read()
.Проблема в том, что он вызывается при каждом запросе, когда я думал, что он вызывается только тогда, когда Result Is Nothing
Я что-то здесь упускаю?
РЕДАКТИРОВАТЬ: и для вас c # ребята, вот эквивалент C #
public static class CacheExtensions
{
private static object sync = new object();
public const int DefaultCacheExpiration = 20;
public static T GetOrStore<T>( this Cache cache, string key, Func<T> generator ) {
return cache.GetOrStore( key, generator != null ? generator() : default( T ), DefaultCacheExpiration );
}
public static T GetOrStore<T>( this Cache cache, string key, Func<T> generator, double expireInMinutes ) {
return cache.GetOrStore( key, generator != null ? generator() : default( T ), expireInMinutes );
}
public static T GetOrStore<T>( this Cache cache, string key, T obj ) {
return cache.GetOrStore( key, obj, DefaultCacheExpiration );
}
public static T GetOrStore<T>( this Cache cache, string key, T obj, double expireInMinutes ) {
var result = cache[key];
if ( result == null ) {
lock ( sync ) {
if ( result == null ) {
result = obj != null ? obj : default( T );
cache.Insert( key, result, null, DateTime.Now.AddMinutes( expireInMinutes ), Cache.NoSlidingExpiration );
}
}
}
return (T)result;
}
}
и вызов
return HttpRuntime.Cache.GetOrStore<List<string>>("TagNamesOnly", () => _TagRepository.Read().Select(t => t.Name).OrderBy(t => t).ToList());