1

我正在考虑我的 asp.net 应用程序中的两种模式,我想通过静态方法或使用 asp.net 缓存来减少代码执行的开销。它们如下。

  1. 静态方法

    Private Shared _transforms As New System.Collections.Generic.Dictionary(Of System.Type, MyObject)()
    Private Shared Function Load(theType As System.Type) As MyObject
    Dim lockAquired As Boolean
    If Not _transforms.ContainsKey(theType) Then
        Try
            lockAquired = Monitor.TryEnter(_synchInstanceLock, LOCK_TIME_OUT)
             '...DO MY MEMORY INTENSIVE TASK HERE
            _transforms.Add(theType, doc)
        Catch ex As Exception
            Throw (ex)
        Finally
            If lockAquired = True Then
                Monitor.Exit(_synchInstanceLock)
            End If
        End Try
    End If
    Return _transforms(theType)
    

    结束功能

  2. ASP.NET 缓存,注意:Cache 只是 ASP.NET Application[""] Cache 的包装器

    Private Function Load(theTypeAs System.Type) As MyObject
    Dim doc As MyObject = Nothing
    Dim lockAquired As Boolean
    Try
        lockAquired = Monitor.TryEnter(_synchInstanceLock, LOCK_TIME_OUT)
        Dim key As String = GenerateCacheKey(GetType(MyObject), theType.Name)
        Dim cacheData As MyObject = TryCast(Cache(key), MyObject)
        If cacheData Is Nothing Then
        '...DO MY MEMORY INTENSIVE TASK HERE
            Cache.Insert(key, doc)
        Else
            doc = TryCast(cacheData, MyObject)
        End If
    Catch ex As Exception
        Throw (ex)
    Finally
        If lockAquired = True Then
            Monitor.Exit(_synchInstanceLock)
        End If
    End Try
    Return doc
    

    结束功能

它适用于 .NET 3.5

有人可以建议在性能和线程安全方面哪个更好吗?

谢谢

4

1 回答 1

0

您的第一个版本使用 a Dictionary,它不是线程安全的,并尝试使用同步来使访问线程安全。就目前而言,即使没有获得锁,您也会更新字典,因此它不是线程安全的。

您最好使用 aConcurrentDictionary并摆脱锁定代码。

如果我理解正确,您的第二个版本正在使用该HttpApplicationState对象,这与“缓存”不同 - 通常使用该System.Web.Caching.Cache对象。在任何一种情况下,字典都是线程安全的,并且您的锁定代码是多余的。

当然,这些都没有说明访问从字典中检索到的对象成员的线程安全性。如果它是不可变的,你会没事的,否则你可能需要额外的同步。

于 2013-06-26T09:58:39.767 回答