这段代码线程安全吗?

时间:2010-04-29 13:15:50

标签: asp.net vb.net

''' <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

2 个答案:

答案 0 :(得分:3)

<击>否。 ASP.NET缓存本身并不是线程安全的,看起来您正在缓存中创建对象,具体取决于它们是否存在。

您需要在写入时锁定缓存。

让我用不同的方式说出一些事情。事实上,代码是线程安全的。您目前编码的方式可能会导致多线程情况下的性能问题。

在这种情况下,多个用户将同时运行相同的代码,理论上同时访问和修改相同的缓存对象。随着这种情况的扩大,性能会受到影响。

创建锁定将提高重负载下的性能(同时在轻负载下施加轻微的开销),因为由于缓存问题,您将无法无提取地获取数据。

答案 1 :(得分:1)

根据MSDN文档,System.Web.Caching.Cache类是线程安全的。但是,该文档还显示了一个示例,其中在没有锁定的情况下对高速缓存执行读取和写入。这不可能是线程安全的,因为写入取决于读取。您发布的代码基本上就像示例。我绝对建议锁定整个方法。