2008-10-04 45 views
2

在一些ASP教程,像this,我觀察到以下模式:應用程序對象和併發參與討論

Application.Lock

「做一些事情與應用對象

Application.Unlock

但是,由於網頁可以有多個實例,因此存在明顯的併發問題米所以我的問題如下:

如果一個頁面試圖鎖定,而對象已被鎖定,該怎麼辦?

有沒有辦法來檢測應用程序對象是否被鎖定?

只是在解鎖的應用程序對象上工作還是會產生其他後果?

如果只有一個涉及應用程序對象的操作,該怎麼辦? 〜在這種情況下是否有理由鎖定/解鎖?

回答

3

MSDN documentation

Lock方法塊其他客戶從修改存儲在應用程序對象中的變量,以確保只有一個在一個時間客戶端可以改變或訪問應用程序的變量。

如果不叫Application.Unlock方法明確,服務器解鎖鎖定應用程序對象時,.asp文件結束或超時

應用程序對象上的鎖持續很短的時間,因爲應用程序對象在頁面完成處理或超時時解鎖。

如果一個頁面鎖定應用程序對象,並且第二個頁面在第一個頁面仍然鎖定時嘗試執行相同操作,則第二個頁面將等待第一個頁面完成,或者直到達到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。

+0

這是從[MSDN參考頁'Application.Lock`](http://msdn.microsoft.com/zh-cn/library/ms525184.aspx)複製並粘貼的 - 沒有適當的信用。 – Lumi 2011-11-29 00:12:27

1

如果一個頁面在已鎖定的應用程序對象上嘗試鎖定,它將一直等到持有該鎖定的頁面釋放它。這通常會很快(ASP代碼通常應該持續足夠長的時間才能訪問存儲在應用程序中的共享對象)。

2

如果您使用解鎖的應用程序對象,會有後果。例如,如果你想實現一個全局計數器: -

Application("myCounter") = Application("myCounter") + 1 

上述代碼有時會錯號。此代碼讀取,添加和分配。如果兩個線程同時嘗試執行此操作,則它們可能會讀取相同的值,然後將相同的值遞增myCounter 1而不是2.

需要什麼是確保第二個線程無法讀取myCounter直到第二個線程寫入它爲止。因此,這是更好的: -

Application.Lock 

Application("myCounter") = Application("myCounter") + 1 

Application.Unlock 

當然也有併發問題鎖被保持較長時間,特別是如果有其他用途的應用程序,它是由代碼持有鎖的影響。

因此,您應該避免需要長時間鎖定應用程序的設計。