''' <summary>
''' Returns true if a submission by the same IP address has not been submitted in the past n minutes.
'' </summary>
Protected Function EnforceMinTimeBetweenSubmissions(ByVal minTimeBetweenRequestsMinutes as Integer) As Boolean
If minTimeBetweenRequestsMinutes = 0 Then
Return True
End If
If Cache("submitted-requests") Is Nothing Then
Cache("submitted-requests") = New Dictionary(Of String, Date)
End If
' Remove old requests. '
Dim submittedRequests As Dictionary(Of String, Date) = CType(Cache("submitted-requests"), Dictionary(Of String, Date))
Dim itemsToRemove = submittedRequests.Where(Function(s) s.Value < Now).Select(Function(s) s.Key).ToList
For Each key As String In itemsToRemove
submittedRequests.Remove(key)
Next
If submittedRequests.ContainsKey(Request.UserHostAddress) Then
' User has submitted a request in the past n minutes. '
Return False
Else
submittedRequests.Add(Request.UserHostAddress, Now.AddMinutes(minTimeBetweenRequestsMinutes))
End If
Return True
End Function
答案 0 :(得分:3)
<击>否。 ASP.NET缓存本身并不是线程安全的,看起来您正在缓存中创建对象,具体取决于它们是否存在。
您需要在写入时锁定缓存。
让我用不同的方式说出一些事情。事实上,代码是线程安全的。您目前编码的方式可能会导致多线程情况下的性能问题。
在这种情况下,多个用户将同时运行相同的代码,理论上同时访问和修改相同的缓存对象。随着这种情况的扩大,性能会受到影响。
创建锁定将提高重负载下的性能(同时在轻负载下施加轻微的开销),因为由于缓存问题,您将无法无提取地获取数据。
答案 1 :(得分:1)
根据MSDN文档,System.Web.Caching.Cache
类是线程安全的。但是,该文档还显示了一个示例,其中在没有锁定的情况下对高速缓存执行读取和写入。这不可能是线程安全的,因为写入取决于读取。您发布的代码基本上就像示例。我绝对建议锁定整个方法。