Путаница с многопоточностью рабочего процесса - PullRequest
0 голосов
/ 05 марта 2012

Попробуйте открыть следующую страницу в двух разных вкладках в вашем браузере. нажмите кнопку обновления, чтобы избежать получения страницы из кэша браузера:

    protected void Page_Load(object sender, EventArgs e)
    {
        Thread.Sleep(10000);
        Response.Write(DateTime.Now.ToString());
    }

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

Теперь создайте следующие страницы, и GlobalCustomClass

GlobalCustomClass

public class GlobalCustomClass
    {
        public static string GlobalVariable
        {
            get;
            set;
        }
    }

Default.aspx

protected void Page_Load(object sender, EventArgs e)
        {
            GlobalCustomClass.GlobalVariable = "Default page";
            Thread.Sleep(10000);
            Response.Write(DateTime.Now.ToString());
            Response.Write("<br />");
            Response.Write(GlobalCustomClass.GlobalVariable);
        }

Page2.aspx

 protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(DateTime.Now.ToString());
            Response.Write("<br />");
            GlobalCustomClass.GlobalVariable = "Page2";
            Response.Write(GlobalCustomClass.GlobalVariable);

        }

Обновить страницу по умолчанию, и до истечения 10 секунд обновить страницу 2 ... Default.aspx отображает «страницу 2». Да, это не потокобезопасно.

Теперь попробуйте это, откройте следующую страницу в двух вкладках браузера:

    protected void Page_Load(object sender, EventArgs e)
    {
         Session["x"] = "ABC";
         Thread.Sleep(10000);
         Response.Write(DateTime.Now.ToString());
    }

Теперь кажется, что первый поток блокируется на объекте сеанса, а другой должен ждать целых 10 секунд !!

Теперь попробуйте Первый случай, но поместите Global.ascx в проект ... и скажите что, первый поток блокируется на чем-то !!!!!

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

Если у вас есть Backend-приложение, содержащее отчет, для визуализации которого требуется 30 секунд. и если 60 пользователей откроют этот отчет, то пользователь с номером 61 будет ждать полчаса, пока страница загрузится в его браузер !! Это типичная нить голода !! и меня, вероятно, уволят: (

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

2) Как исправить эту ситуацию?

3) По какой теме я должен исследовать это? Вы знаете хорошую книгу?

Спасибо

Ответы [ 4 ]

4 голосов
/ 05 ноября 2012

Если вам нужны параллельные запросы от одного и того же пользователя, вы можете

  1. отключить состояние сеанса или
  2. установить для сеанса значение ReadOnly в директиве страницы.

Очевидно, что если состояние сеанса только для чтения, вы не можете писать в него, но вы все равно можете прочитать его, чтобы выяснить, кто пользователь и т. Д.

4 голосов
/ 05 марта 2012

и если 60 пользователей откроют этот отчет, то пользователь с номером 61 будет ждать полчаса до загрузки страницы в его браузер !!

Это не так, потому что блокировка только для сеанса , но не глобальная для всех пользователей / сеансов.

Поскольку вы использовали один и тот же браузер для вызова двух страниц, вы также использовали один и тот же сеанс ASP.NET (поскольку обе вкладки совместно используют файл cookie сеанса ASP.NET). Если вы используете два разных браузера для симуляции двух пользователей, вы увидите, что второй пользователь не будет заблокирован в течение 20 секунд.

Кроме того, блокировка, конечно, происходит, только если вы используете состояние сеанса. Если вы хотите создать высокопроизводительное веб-приложение (с множеством одновременных пользователей или одновременных / асинхронных запросов), вам следует как можно больше избегать состояния сеанса.

2 голосов
/ 05 марта 2012

Давайте посмотрим на документы:

Параллельные запросы и доступ к состоянию сеанса к состоянию сеанса ASP.NET является эксклюзивным для сеанса, что означает, что если два разных пользователя одновременные запросы, доступ к каждому отдельному сеансу предоставляется одновременно. Однако, если два одновременных запроса сделаны для тот же сеанс (с использованием того же значения SessionID), первый запрос получает эксклюзивный доступ к информации о сеансе. Второй запрос выполняется только после завершения первого запроса. (Вторая сессия может также получить доступ, если исключена блокировка эксклюзивной информации потому что первый запрос превышает время ожидания блокировки.) Если Значение EnableSessionState в директиве @ Page установлено в ReadOnly, запрос информации о сеансе только для чтения не приводит к эксклюзивная блокировка данных сеанса. Тем не менее, запросы только для чтения данные сеанса все еще могут ждать блокировки, установленной для чтения-записи запрос на очистку данных сеанса.

С http://msdn.microsoft.com/en-us/library/ms178581.aspx

Так что только один и тот же пользователь будет вынужден ждать. Блокировка существует, но только для пользователя.

1 голос
/ 05 марта 2012

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

Я не согласен. Допустим, у вас есть сайт со страницей, выполнение которой занимает всего 100 мс, но поддерживает 1000 одновременных пользователей. По вашей логике, до завершения последнего запроса может потребоваться 100 тыс. Мс. Очевидно, что это не относится к сайтам с высоким трафиком.

Я сомневаюсь, что на ViewState установлена ​​какая-либо блокировка (почему бы? Это относится только к текущему экземпляру страницы).

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

Даже в .NET 1.1 я проводил тестирование параллелизма с помощью инструментов VS ( Application Center Test ) и - хотя трафик, безусловно, замедляет работу сайта - тысячи дорогостоящих запросов не создают линейное узкое место, которое вы описываете.

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

...