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 是否应该在执行写入操作(使用AddSet)时不处理情况,没有其他线程应该能够读取(确保向读者提供无效数据的情况)?我可能是错的,但我想不出任何这样的情况。你也可以举个例子吗? @CSharpLearner:在上面的示例中,有一个读取和一个写入。每个线程本身都是受保护的,但是两个线程可以在另一个线程执行写入之前相互读取,两个线程都会获取数据然后尝试添加它。 谢谢。我在想一些不同的东西。在ReaderWriterLock 中,一次只能写入一个线程,从而阻止其他线程读取或写入。正确的?因此,访问相同代码的并行线程将等到第一个线程完成写入。当第一个线程完成时,其他线程上的写操作将恢复。我对吗?在这种情况下,如果您的插图中的FetchInfoFromDatabase() 不是繁重且耗时的操作,那么显式锁定/解锁是否很重要? 如果您可以将您的专家评论发布到***.com/questions/15629478/…,那就太好了。【参考方案2】:

HttpApplicationState - 全局访问变量对所有

可见

正在使用该应用程序的用户。所以为了避免更改时的竞争条件

变量的值。我们需要一些预防措施,这就是我们使用的原因

Application.Lock() 并在工作完成后将相同的变量释放给其他人

使用 Application.Unlock() 排队

Application.Lock()
Application("VisitorCount") = Convert.ToInt32(Application("VisitorCount")) + 1
Application.UnLock()

【讨论】:

以上是关于HttpApplicationState - 如果它是线程安全的,为啥存在竞争条件?的主要内容,如果未能解决你的问题,请参考以下文章

application详解

我可以从 HttpModule 实例中放弃 InProc ASP.NET 会话吗

如果是主页,如果是页面,如果是单页,否则如果

如果复选框选中禁用其他,如果未选中启用所有 JavaScript?

检查记录是不是存在,如果是,则“更新”,如果不“插入”

Jquery“如果这个和如果那个”然后这样做