HttpApplicationState - 如果它是线程安全的,为啥存在竞争条件?
Posted
技术标签:
【中文标题】HttpApplicationState - 如果它是线程安全的,为啥存在竞争条件?【英文标题】:HttpApplicationState - Why does Race condition exist if it is thread safe?HttpApplicationState - 如果它是线程安全的,为什么存在竞争条件? 【发布时间】:2010-12-04 05:45:10 【问题描述】:我刚刚阅读了一篇文章,描述了 HttpApplicationState 如何使用AcquireRead() / AcquireWrite()
函数来管理并发访问。它继续解释说,在某些情况下,我们需要在 Application 对象上使用显式 Lock()
和 Unlock()
以避免竞争条件。
如果对象隐式处理并发访问,我无法理解为什么应用程序状态应该存在竞争条件。
有人可以向我解释一下吗?为什么我需要使用 Application.Lock()
和 Application.Unlock()
?谢谢!
【问题讨论】:
【参考方案1】:AcquireRead 和 AcquireWrite 方法在内部 HttpApplicationStateLock 类中,因此您不要自己使用它们。它们同步访问,但仅用于单次读取或写入。如果您需要同步访问,请从您的代码中使用 Lock 和 Unlock 方法。
如果您更改的不是单次读取或写入,通常需要同步访问,例如添加两个相互依赖的应用程序项,或者首先检查一个项是否存在然后添加:
Application.Lock()
if (Application["info"] == null)
Application.Add("info", FetchInfoFromDatabase());
Application.Unlock();
【讨论】:
令人困惑。如果是这种情况,Microsoft 会保证什么样的线程安全?ReaderWriterLock
是否应该在执行写入操作(使用Add
,Set
)时不处理情况,没有其他线程应该能够读取(确保向读者提供无效数据的情况)?我可能是错的,但我想不出任何这样的情况。你也可以举个例子吗?
@CSharpLearner:在上面的示例中,有一个读取和一个写入。每个线程本身都是受保护的,但是两个线程可以在另一个线程执行写入之前相互读取,两个线程都会获取数据然后尝试添加它。
谢谢。我在想一些不同的东西。在ReaderWriterLock
中,一次只能写入一个线程,从而阻止其他线程读取或写入。正确的?因此,访问相同代码的并行线程将等到第一个线程完成写入。当第一个线程完成时,其他线程上的写操作将恢复。我对吗?在这种情况下,如果您的插图中的FetchInfoFromDatabase()
不是繁重且耗时的操作,那么显式锁定/解锁是否很重要?
如果您可以将您的专家评论发布到***.com/questions/15629478/…,那就太好了。【参考方案2】:
HttpApplicationState - 全局访问变量对所有
可见正在使用该应用程序的用户。所以为了避免更改时的竞争条件
变量的值。我们需要一些预防措施,这就是我们使用的原因
Application.Lock() 并在工作完成后将相同的变量释放给其他人
使用 Application.Unlock() 排队
Application.Lock()
Application("VisitorCount") = Convert.ToInt32(Application("VisitorCount")) + 1
Application.UnLock()
【讨论】:
以上是关于HttpApplicationState - 如果它是线程安全的,为啥存在竞争条件?的主要内容,如果未能解决你的问题,请参考以下文章
我可以从 HttpModule 实例中放弃 InProc ASP.NET 会话吗