SessionStateAttribute с поведением Disabled, кажется, не работает? - PullRequest
0 голосов
/ 07 апреля 2019

Я только что знал о блокировке состояния сеанса, поэтому я пытаюсь протестировать отключение такого рода блокировок с помощью простого проекта MVC (по умолчанию при создании нового проекта MVC).

Вот HomeController с единственным задействованным About методом действия:

[SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
    static int c = 0;
    static long ci;
    [Authorize]
    public ActionResult About()
    {
        var isSecondRequest = ++c == 2;
        //Session["a"] = 1;
        Debug.Print(">>> Started working ..." + DateTime.Now);
        if (isSecondRequest)
        {
            Debug.Print(">>> current counter: " + ci);
            for (long i = 0; i < 10000000000; i++) ;
        }            
        else
        {
            for (ci = 0; ci < 10000000000; ci++) ;
        }
        Debug.Print(">>> Finished!");
        return Content("welcome");
    }

}

Я проверяю это, сначала открывая две вкладки домашней страницы. Затем попробуйте щелкнуть ссылку About на первой вкладке и почти сразу переключиться на вторую вкладку, чтобы щелкнуть About еще раз. Поэтому я ожидаю, что строка >>> Started working … должна быть напечатана 2 раза с почти одинаковыми временными метками или с небольшой разницей в 1 или 2 секунды, но фактическая разница составляет до 21 секунд , например:

>>> Started working ...4/7/2019 3:16:15 PM
>>> Started working ...4/7/2019 3:16:36 PM

Так что это означает, что второй запрос все еще заблокирован, что неожиданно, когда я уже применил атрибут SessionStateAttribute с поведением Disabled к HomeController. И действительно, похоже, что он работает в другом смысле, что Session равен null для каждого запроса.

Не могли бы вы заметить здесь что-то не так? Моя общая цель - отключить блокировку такого типа, чтобы я мог вручную управлять одновременными запросами и немедленно возвращать клиенту некоторые полезные сообщения (например, для второго запроса), чтобы он не выглядел как занятый без необходимости.

Ответы [ 2 ]

0 голосов
/ 07 апреля 2019

Я действительно не уверен, что ты делаешь неправильно.Я только что создал совершенно новое приложение MVC, используя VS2017.Я взял HomeController и добавил атрибут [SessionState(SessionStateBehavior.Disabled)].Затем я добавил следующий код в метод Index:

public ActionResult Index()
{
    this.ViewBag.Start = DateTime.Now;
    System.Threading.Thread.Sleep(5000);
    this.ViewBag.End = DateTime.Now;
    return View();
}

На мой взгляд, я добавил:

<div class="row">
    <div class="col-xs-6">Start: @this.ViewBag.Start.ToString("HH:mm:ss.fffffff")</div>
    <div class="col-xs-6">End: @this.ViewBag.End.ToString("HH:mm:ss.fffffff")</div>
</div>

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

Tab1: Start: 21:10:41.3620017, End: 21:10:46.3623676
Tab2: Start: 21:10:42.4819327, End: 21:10:47.4824334

Итак, вы можете легко видеть, что они обрабатываются одновременно.

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

Я также пробовал это с вашим кодом (с циклом for, измененным наThread.Sleep) и проверка подлинности Windows.Работает как надо.В других моих проектах я обычно использую проверку подлинности с помощью форм, и у меня никогда не было с ней проблем.Какую аутентификацию вы используете?

0 голосов
/ 07 апреля 2019

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

public class SecondaryController : Controller
{
    // GET: Secondary
    public ActionResult Index()
    {
        Debug.Print(">>> Started working ..." + DateTime.Now);
        Thread.Sleep(10000);
        Debug.Print(">>> Finished!");
        return Content("welcome");
    }
}

Вместе с

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }


    public ActionResult About()
    {
        Debug.Print(">>> Started working ..." + DateTime.Now);
        Thread.Sleep(10000);
        Debug.Print(">>> Finished!");
        return Content("welcome");
    }

}

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

Начал работать ... 7/4/2019 13:01:49

Начал работать ... 7/4/2019 13:01:52

Готово! * * 1013

Готово!

Здесь может быть интересно следующее

"Вот в чем дело - у IRouteHandler есть один метод - GetHttpHandler. Когда вы делаете ASP.Net MVC-запрос к контроллеру, по умолчанию механизм маршрутизации обрабатывает запрос, создавая новый экземпляр MvcRouteHandler, который возвращает MvcHandler. MvcHandler. является реализацией IHttpHandler, которая помечена (удивительно!) интерфейсом IRequiresSessionState. Вот почему обычный запрос использует Session. "

Взято из Отключить состояние сеанса для каждого запроса в ASP.Net MVC

...