更新具有绝对过期的缓存项

时间:2013-11-07 09:46:01

标签: asp.net .net vb.net

有没有办法更新内存缓存中的项目并保持其绝对过期策略?

我正在编写一个简单的限制类来检查是否应该限制请求。 例如,如果>节流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

1 个答案:

答案 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