代码之家  ›  专栏  ›  技术社区  ›  Achilles

我应该用吗应用程序。锁定()?

  •  2
  • Achilles  · 技术社区  · 14 年前

    考虑以下情况:我正在使用 Application 中的对象ASP.NET存储收藏( List(of MyObject) )由多个用户同时访问的。虽然我知道从应用程序对象读取是线程安全的,但我想知道应该如何使此代码线程安全:

    objList = Application("GlobalList")
    
    objList.add(AnotherValue)
    
    application("GlobalList") = objList
    

    objList = Application("GlobalList")
    
    dim PrunedList as MyObject() = (from o as MyObject in objList where o.SomeProperty = SomeValue).ToArray()
    
    objList.Clear()
    
    For each PrunedListObject as MyObject in PrunedList
       objList.add(PrunedListObject)
    next
    
    application("GlobalList") = objList
    

    我读了一些关于应用程序。锁定()基本上是一个互斥体,但我担心在操作时阻塞其他线程会对性能造成影响 Application("GlobalList") 是应用程序。锁定()正确的方法?

    1 回复  |  直到 14 年前
        1
  •  2
  •   Josh    14 年前

    我不是这方面的专家ASP.NET具体来说,但我确实用了几年。应用程序的存储空间很大程度上是为了与传统的ASP向后兼容。您将需要try/finally块来锁定和解锁,而且它仍然不如在.NET中使用一些经典ASP中没有的其他锁定机制灵活。

    在您的示例中,Lock/Unlock需要非常广泛,因为即使在获取了“GlobalList”之后,多个线程同时写入这个集合仍然会导致并发问题。

    您可以在根本不使用应用程序存储的情况下执行这样的操作。请注意,您仍然需要同步对集合的访问,但不需要锁定/解锁整个应用程序状态字典。

    Private Shared GlobalList As New List(Of Foo)()
    
    ...
    
    SyncLock GlobalList
        // Only one thread can proceed here at a time
    End SyncLock
    

    ReaderWriterLockSlim 这允许多个读卡器同时执行,只要没有持有锁的写入程序。当读者比作者多时,这会使您的性能显著提高。不过,使用这种锁有点棘手,因为没有像C#的lock语句或VB的SyncLock那样的语法糖分。

    编辑

    http://blogs.msdn.com/b/pedram/archive/2007/10/07/a-performance-comparison-of-readerwriterlockslim-with-readerwriterlock.aspx