有没有办法更新内存缓存中的项目并保持其绝对过期策略?
我正在编写一个简单的限制类来检查是否应该限制请求。 例如,如果>节流1分钟内5个请求。
我将请求数量存储在缓存对象中,该对象将在1分钟后过期。
每次访问对象时,请求的数量都会增加,但我无法弄清楚如何将对象放回缓存中,而无需重新插入新的绝对到期时间。
有没有办法在没有重新插入的情况下更新对象?
例如:
''' <summary>
''' Methods and properties related to throttling requests.
''' </summary>
''' <remarks>
''' Data is persisted to the Local cache and need not be consistant across web farm or web garden environment.
''' </remarks>
Public Class Throttle
Private Property CacheKey As String
Private Property CacheObject As Object
Public Property ThrottleCounter As Integer
Public Sub New()
'set the cache key:
Me.CacheKey = String.Format("Throttle_{0}", userID)
IncrementThrottle()
End Sub
Private Sub IncrementThrottle()
'get existing cache object:
Me.CacheObject = HttpRuntime.Cache.Item(Me.CacheKey)
If IsNothing(Me.CacheObject) Then
'create cache object:
Me.ThrottleCounter = 0
HttpRuntime.Cache.Insert(Me.CacheKey, Me.ThrottleCounter, Date.Now.AddMinutes(1), Caching.Cache.NoSlidingExpiration, CacheItemPriority.Low)
Else
Try
Me.ThrottleCounter = Cint(Me.CacheObject)
Catch ex As Exception
Me.ThrottleCounter = 0
End Try
End If
Me.ThrottleCounter += 1
'###########################################################################
'update item in cache:
'I want to put the updated value back in the cache and maintain the absolute expiration.
'###########################################################################
End Sub
''' <summary>
''' Returns True if the request should be throttled.
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function IsThrottled() As Boolean
Return Me.ThrottleCounter > 5
End Function
End Class
答案 0 :(得分:1)
我通过创建一个自定义对象来解决这个问题,该对象将ExpiryDate值存储在缓存中,然后通过计算当前日期/时间和原始到期日期/时间的差异,将对象重新插入到具有新的到期日期的缓存中。
示例:
Public Class Throttle
Private Property CacheKey As String
Public Property CacheData As CacheObject
Public Class CacheObject
Public RequestCounter As Integer
Public ExpiryDate As Date
End Class
Public Sub New()
Me.CacheKey = String.Format("Throttle_{0}", userID)
IncrementThrottle()
End Sub
Private Sub IncrementThrottle()
'get existing cache object:
Dim cacheObj As Object = HttpRuntime.Cache.Item(Me.CacheKey)
If Not IsNothing(cacheObj) Then
Try
Me.CacheData = CType(cacheObj, CacheObject)
Catch ex As Exception
cacheObj = Nothing
End Try
End If
If IsNothing(cacheObj) Then
'create new cache object:
Me.CacheData = New CacheObject
With Me.CacheData
.RequestCounter = 1
.ExpiryDate = Date.Now.AddMinutes(1)
End With
'insert it to cache:
HttpRuntime.Cache.Insert(Me.CacheKey, Me.CacheData, Me.CacheData.ExpiryDate, Caching.Cache.NoSlidingExpiration, CacheItemPriority.Low)
Else
'calculate the time difference:
Dim ts As TimeSpan = Date.Now.Subtract(Me.CacheData.ExpiryDate)
'reinsert item into cache:
Me.CacheData.RequestCounter += 1
HttpRuntime.Cache.Insert(Me.CacheKey, Me.CacheData, Date.Now.Subtract(ts), Caching.Cache.NoSlidingExpiration, CacheItemPriority.Low)
End If
End Sub
Public Function IsThrottled() As Boolean
Return Me.CacheData.RequestCounter > 5
End Function
End Class