在一些asp教程中,如this,我观察到以下模式:
Application.Lock
'用应用程序对象做一些事情
Application.Unlock
但是,由于网页可以有多个实例,因此存在明显的并发问题。所以我的问题如下:
如果一个页面在对象已被锁定时尝试锁定该怎么办?
有没有办法检测应用程序对象是否被锁定?
仅仅处理未锁定的应用程序对象是否更好,还是会产生其他后果?
如果只有一个涉及应用程序对象的操作怎么办? 〜在这种情况下是否有理由锁定/解锁?
答案 0 :(得分:3)
Lock
方法阻止其他客户修改存储在Application对象中的变量,确保一次只有一个客户可以更改或访问应用程序变量。
如果未明确调用 Application.Unlock
方法,则当.asp文件结束或超时时,服务器会解锁锁定的Application对象。
Application对象上的锁定会持续很短的时间,因为当页面完成处理或超时时,应用程序对象将被解锁。
如果一个页面锁定了应用程序对象,而第二个页面在第一个页面仍然锁定时尝试执行相同操作,则第二个页面将等待第一个页面完成,或者直到达到Server.ScriptTimeout
限制
一个例子:
<%@ Language="VBScript" %>
<%
Application.Lock
Application("PageCalls") = Application("PageCalls") + 1
Application("LastCall") = Now()
Application.Unlock
%>
This page has been called <%= Application("PageCalls") %> times.
在上面的示例中,Lock
方法一次阻止多个客户端访问变量PageCalls 。如果应用程序尚未锁定,则两个客户端可以同时尝试增加变量PageCalls。
答案 1 :(得分:2)
如果您使用解锁的应用程序对象,将会产生后果。例如,如果要实现全局计数器: -
Application("myCounter") = Application("myCounter") + 1
以上代码有时会错误计算。此代码读取,添加和分配。如果两个线程同时尝试执行此操作,则它们可能会读取相同的值,然后写入相同的值,将myCounter递增1而不是2。
需要的是确保第二个线程在第二个线程写入之前无法读取myCounter。因此这更好: -
Application.Lock
Application("myCounter") = Application("myCounter") + 1
Application.Unlock
当然,如果锁保持很长时间会出现并发问题,特别是如果应用程序的其他用途不受持有锁的代码的影响。
因此,您应该避免需要对应用程序进行长时间锁定的设计。
答案 2 :(得分:1)
如果一个页面在已经锁定的情况下尝试锁定它,它将等待持有锁定的页面释放它。这通常很快(ASP代码通常只能保持锁定的时间足以访问存储在Application中的共享对象)。