Объект приложения и проблемы параллелизма - PullRequest
2 голосов
/ 04 октября 2008

В некоторых уроках asp, таких как this , я наблюдаю следующую схему:

Application.Lock

'сделать некоторые вещи с объектом приложения

Application.Unlock

Однако, поскольку веб-страницы могут иметь несколько экземпляров, существует очевидная проблема параллелизма. Итак, мои вопросы следующие:

Что если одна страница попытается заблокировать, когда объект уже заблокирован?

Есть ли способ определить, заблокирован ли объект приложения?

Лучше просто работать с разблокированным объектом приложения или это имеет другие последствия?

Что, если существует только одно действие с объектом приложения? ~ Есть ли в этом случае причина для блокировки / разблокировки?

Ответы [ 3 ]

3 голосов
/ 04 октября 2008

Из документации MSDN :

Метод Lock блокирует другие клиенты от изменения переменных, хранящихся в объекте Application, гарантируя, что только один клиент за раз может изменять или обращаться к переменным приложения. 1010 *

Если вы не вызываете метод Application.Unlock явным образом, сервер разблокирует заблокированный объект Application, когда файл .asp заканчивается или истекает время .

Блокировка объекта 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.

2 голосов
/ 04 октября 2008

Последствия будут, если вы используете разблокированный объект приложения. Например, если вы хотите реализовать глобальный счетчик: -

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

Приведенный выше код будет время от времени пропадать. Этот код читает, добавляет и присваивает. Если два потока пытаются выполнить это одновременно, они могут прочитать одно и то же значение, а затем записать одно и то же значение, увеличивая myCounter на 1 вместо 2.

Необходимо убедиться, что второй поток не может прочитать myCounter, пока второй поток не записал в него. Следовательно, это лучше: -

Application.Lock

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

Application.Unlock

Конечно, существуют проблемы с параллелизмом, если блокировка удерживается в течение длительного времени, особенно если существуют другие применения для приложения, на которые не влияет код, удерживающий блокировку.

Следовательно, вам следует избегать дизайна, который потребовал бы длительной блокировки приложения.

1 голос
/ 04 октября 2008

Если одна страница пытается заблокировать объект Application, пока он уже заблокирован, она будет ждать, пока страница, содержащая блокировку, не освободит его. Обычно это происходит быстро (ASP-код обычно должен удерживать блокировку достаточно долго, чтобы получить доступ к общему объекту, который хранится в приложении).

...