Блокируется сессия при выполнении длинной операции
От: bubuka115  
Дата: 15.08.07 06:35
Оценка:
Если посетитель запускает выполнение длинной операции, то сайт перестает ему отвечать, пока не отработает.
Как я понял затык происходит при восстановлении сессии, так как если сессия пустая, то проблемы не возникает.
С этим поведением как-нибудь можно бороться?
Re: Блокируется сессия при выполнении длинной операции
От: Дюша Россия http://www.danfoss.com/russia
Дата: 15.08.07 06:42
Оценка:
Здравствуйте, bubuka115, Вы писали:

B>длинной операции

Насколько длинной?

B>при восстановлении сессии

???

B>если сессия пустая

Это как?

Re[2]: Блокируется сессия при выполнении длинной операции
От: bubuka115  
Дата: 15.08.07 06:52
Оценка:
Здравствуйте, Дюша, Вы писали:

Д>Здравствуйте, bubuka115, Вы писали:


B>>длинной операции

Д>Насколько длинной?
Не имеет значения, пусть будет минута

B>>при восстановлении сессии

Д>???
При подключении объекта Session

B>>если сессия пустая

Д>Это как?
Это так, что в коллекции Session ничего нет.
Re: Блокируется сессия при выполнении длинной операции
От: Koxa  
Дата: 15.08.07 06:59
Оценка:
Здравствуйте, bubuka115, Вы писали:

B>Если посетитель запускает выполнение длинной операции, то сайт перестает ему отвечать, пока не отработает.

B>Как я понял затык происходит при восстановлении сессии, так как если сессия пустая, то проблемы не возникает.
B>С этим поведением как-нибудь можно бороться?

<%@ Page ... EnableSessionState="false"%>
или
<%@ Page ... EnableSessionState="ReadOnly"%>

Понимать только к чему это приводит...
Re[2]: Блокируется сессия при выполнении длинной операции
От: Овощ http://www.google.com
Дата: 15.08.07 07:12
Оценка:
Session State Overview

Concurrent Requests and Session State

Access to ASP.NET session state is exclusive per session, which means that if two different users make concurrent requests, access to each separate session is granted concurrently. However, if two concurrent requests are made for the same session (that is, using the same SessionID value), then the first request received gains exclusive access to the session information and the second request will execute once the first request completes, or until the exclusive lock on the information is freed due to the first request exceeding the lock timeout. If the EnableSessionState page directive is set to ReadOnly, then a request for the read-only session information does not result in an exclusive lock on the session data. Read-only requests for session data may still have to wait for a lock gained by a read-write request for session data to clear.


Доступ к состоянию сессии может быть в двух режимах: эксклюзивным (для записи) и только для чтения. Выбор режима осуществляется на уровне страницы в директиве Page атрибут EnableSessionState. Одновременно только один запрос может получить доступ к состоянию сессии в эксклюзивном режиме. Одновременный доступ нескольких запросов к сессии может быть осуществлен если все они проходят в режиме ReadOnly.
Re[2]: Блокируется сессия при выполнении длинной операции
От: bubuka115  
Дата: 15.08.07 07:17
Оценка:
Здравствуйте, Koxa, Вы писали:

K><%@ Page ... EnableSessionState="false"%>

K>или
K><%@ Page ... EnableSessionState="ReadOnly"%>

K>Понимать только к чему это приводит...


Похоже плохо объяснил проблему.
Скажем посетитель запускает поиск, но наше замечательное приложение не отвечает достаточно быстро. Тогда этот несчастный решает поменять параметры поиска.. А вот и фиг говорим ему мы, пока поиск не выполнен ни куда ты не пойдешь.
Т.е. мы не можем отказаться от сессии. Просто хочется где-нибудь (например в BeginRequest) убивать задумчивый запрос.
Re: Пример
От: bubuka115  
Дата: 15.08.07 07:43
Оценка:
Пример, для тех кто хочет повторить.
Создаем WebSite.

Код страницы
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="?id=1">HyperLink</asp:HyperLink>
        <br />
        <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="?id=2">HyperLink</asp:HyperLink>
        <br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>
    </form>
</body>
</html>

Код класса.
using System;
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //Session["ss"] = "x";
        string id = Request.QueryString["id"];
        if (id == "1")
        {
            DoLong();
        }
        Label1.Text = id;
    }
    private void DoLong()
    {
        string a = string.Empty;
        for (int i = 0; i < 100000; i++)
        {
            a+=i;
        }
    }
}

Кликаем первый линк, затем сразу второй. Все работает.

Раскомментируем линию Session["ss"] = "x"; и второй линк не будет работать пока DoLong не кончит
Re: Решение
От: bubuka115  
Дата: 15.08.07 18:01
Оценка:
Итак, довольно грубое решение.
Запускаем выполнение "тяжелого" метода в новом потоке, добавляем в Application ссылку на поток и подключаемся к нему (Join).
При новом запросе убиваем этот поток.
Первый запрос должен проверить отработал ли метод нормально, или был убит. Если убили, то Response.Close(), или какое-нибудь сообщение пользователю.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.