C# 需要帮助分析.NET缓存扩展方法吗
我有以下分机C# 需要帮助分析.NET缓存扩展方法吗,c#,.net,caching,C#,.net,Caching,我有以下分机 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 Ca
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
除了在\u TagRepository.Read()
上设置断点外,所有这些都非常简单。问题是每次请求都会调用它,而我认为只有当结果为空时才会调用它
我是不是遗漏了什么
编辑:对你们来说,这是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;
}
}
公共静态类缓存扩展
{
私有静态对象同步=新对象();
public const int DefaultCacheExpiration=20;
公共静态T GetOrStore(此缓存、字符串键、Func生成器){
return cache.GetOrStore(key,generator!=null?generator():default(T),DefaultCacheExpiration);
}
公共静态T GetOrStore(此缓存、字符串键、Func生成器、双过期分钟){
return cache.GetOrStore(key,generator!=null?generator():默认值(T),expireInMinutes);
}
公共静态T GetOrStore(此缓存、字符串键、T obj){
返回cache.GetOrStore(key,obj,DefaultCacheExpiration);
}
公共静态T GetOrStore(此缓存、字符串键、T obj、双过期分钟){
var result=cache[key];
如果(结果==null){
锁定(同步){
如果(结果==null){
结果=obj!=null?obj:默认值(T);
Insert(key,result,null,DateTime.Now.AddMinutes(expireInMinutes),cache.noslidingexpirement);
}
}
}
返回(T)结果;
}
}
电话呢
return HttpRuntime.Cache.GetOrStore<List<string>>("TagNamesOnly", () => _TagRepository.Read().Select(t => t.Name).OrderBy(t => t).ToList());
返回HttpRuntime.Cache.GetOrStore(“TagNamesOnly”,()=>\u TagRepository.Read().Select(t=>t.Name).OrderBy(t=>t.ToList());
GetOrStore的签名及其实现不包含对您发送的函数的求值。我真的不知道此刻发生了什么(或者它是否真的起作用)。您似乎正在将Func添加到缓存中
public const int DefaultCacheExpiration = 20;
private static readonly Object SyncRoot = new Object();
public static T GetOrStore<T>(this Cache cache, String key, Func<T> itemGenerator, Double expireInSeconds = DefaultCacheExpiration) {
var item = cache[key];
if (item != null)
return (T)item;
lock (SyncRoot) {
// Fetch a second time to check if anyone have
// added it while we blocked waiting for the lock.
item = cache[key];
if (item != null)
return (T)item;
// Invoke the almighty itemGenerator to execute,
// and generate, the item that should be inserted
// into the cache.
item = itemGenerator.Invoke();
cache.Insert(key, item, null, DateTime.Now.AddSeconds(expireInSeconds), Cache.NoSlidingExpiration);
return (T)item;
}
}
public static T GetOrStore<T>(this Cache cache, String key, T newItem, Double expireInSeconds = DefaultCacheExpiration) {
return cache.GetOrStore(key, () => newItem, expireInSeconds);
}
public const int DefaultCacheExpiration=20;
私有静态只读对象SyncRoot=新对象();
public static T GetOrStore(此缓存、字符串键、Func itemGenerator、Double expireInSeconds=DefaultCacheExpirement){
var item=cache[key];
如果(项!=null)
退货(T)项;
锁定(同步根){
//再找一次来检查是否有人
//在我们阻止等待锁时添加了它。
项=缓存[键];
如果(项!=null)
退货(T)项;
//调用万能的itemGenerator执行,
//并生成应插入的项
//进入缓存。
item=itemGenerator.Invoke();
Insert(key,item,null,DateTime.Now.AddSeconds(expireInSeconds),cache.NoSlidingExpiration);
退货(T)项;
}
}
public static T GetOrStore(此缓存,字符串键,T newItem,Double expireInSeconds=DefaultCacheExpirement){
返回cache.GetOrStore(键,()=>newItem,expireInSeconds);
}
如果这样做不行,请查看您的asp.net缓存设置和服务器上的可用内存量。缓存在内存不足的情况下无法工作。问题在于,您正在调用一个重载的方法来调用您的方法,正如@Simon Svensson指出的,您正在调用的方法不是您发布的方法。这是您实际调用的方法的C版本:
return cache.GetOrStore( key, generator != null ? generator() : default( T ), DefaultCacheExpiration )
您应该马上看到,如果第二个参数传递了非null值,它将调用generator()
已更新
问题与缓存无关,而是您正在调用的重载方法正在执行lambda方法。如果您真的打算按照您概述的方式调用该方法,则必须将其更改为以下内容:
''# Fix StackOverflow Code Coloring Bug
<Extension()>
Public Function GetOrStore(Of T)(ByVal cache As Cache, ByVal key As String, ByVal generator As Func(Of T)) As T
''# Null value to pass to first call. We can not use Nothing because VB can not infer the overload type
Dim NV As Object = Nothing
''# Call the primary method passing a null value
Dim Ret = cache.GetOrStore(key, NV, DefaultCacheExpiration)
''# If that call returns nothing call our generator() method and then re-call the main method
If (Ret Is Nothing) AndAlso (generator IsNot Nothing) Then
Ret = cache.GetOrStore(key, generator(), DefaultCacheExpiration)
End If
Return Ret
End Function
“”#修复StackOverflow代码着色错误
公共函数GetOrStore(Of T)(ByVal缓存作为缓存,ByVal键作为字符串,ByVal生成器作为Func(Of T))作为T
''#传递给第一个调用的空值。我们不能什么都不使用,因为VB不能推断重载类型
作为对象的Dim NV=无
''#调用传递空值的主方法
Dim Ret=cache.GetOrStore(key,NV,DefaultCacheExpiration)
''#如果该调用未返回任何内容,请调用我们的generator()方法,然后重新调用main方法
如果(Ret不为零)和(生成器不为零),则
Ret=cache.GetOrStore(key,generator(),DefaultCacheExpiration)
如果结束
回程网
端函数
我还没有测试过这个,但它或其他非常接近的东西应该会让你得到你想要的。这也是为什么我不是lambdas的超级粉丝。这个想法很好,但是人们倾向于将这么多的代码放在一起,并创建出不太可读的代码。我宁愿有10行可以读,而不是一行可以做同样的事情。如果我在上设置一个断点,那么实际上我也会从中提取代码。如果结果为空,那么
我可以看到结果=正是我需要的结果。我已经编辑了我的问题,以显示整个扩展方法。很抱歉,之前没有说得更清楚。您需要等待调用生成器,直到检查缓存是否不包含您的密钥。你新粘贴的代码包含几个重载,这些重载总是调用生成器。是的,就像我说的,我只是从另一篇文章中获取了一些代码。缓存是我很陌生的一个领域。对不起。缓存肯定是我需要解决的问题,因为我几乎迷路了。如果我在GetOrStore
方法的If(result==null)
行上粘贴断点,我可以看到result
始终填充了正确的数据。因此,生成器
正在生成正确的调用。这只是因为无论缓存是否正确,每次都会命中\u TagRepository
''# Fix StackOverflow Code Coloring Bug
<Extension()>
Public Function GetOrStore(Of T)(ByVal cache As Cache, ByVal key As String, ByVal generator As Func(Of T)) As T
''# Null value to pass to first call. We can not use Nothing because VB can not infer the overload type
Dim NV As Object = Nothing
''# Call the primary method passing a null value
Dim Ret = cache.GetOrStore(key, NV, DefaultCacheExpiration)
''# If that call returns nothing call our generator() method and then re-call the main method
If (Ret Is Nothing) AndAlso (generator IsNot Nothing) Then
Ret = cache.GetOrStore(key, generator(), DefaultCacheExpiration)
End If
Return Ret
End Function