【问题标题】:Static vs Cache in ASP.NET applicationASP.NET 应用程序中的静态与缓存
【发布时间】:2013-06-23 09:13:43
【问题描述】:

我正在考虑我的 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

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

谢谢

【问题讨论】:

  • 只是对您的 try/catch/finally 的批评。您很难保留有关原始异常来源的信息。最好完全删除 catch 代码并将您的代码变成一个简单的 try/finally 块。

标签: asp.net multithreading caching singleton


【解决方案1】:

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

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

如果我理解正确,您的第二个版本使用的是HttpApplicationState 对象,它与“缓存”不同——它通常使用System.Web.Caching.Cache 对象。无论哪种情况,字典都是线程安全的,而您的锁定代码是多余的。

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

【讨论】:

  • 抱歉,我忘了说它适用于 .NET 3.5,所以不能使用 ConccurrentDictionary。
猜你喜欢
  • 2010-09-23
  • 2011-04-26
  • 1970-01-01
  • 2010-11-21
  • 2012-12-18
  • 2012-10-28
  • 1970-01-01
  • 2012-03-26
  • 2018-07-05
相关资源
最近更新 更多