Почему этот веб-контроллер api не работает одновременно?
У меня есть API-интерфейс Web API со следующим методом внутри:
public string Tester()
{
Thread.Sleep(2000);
return "OK";
}
Когда я назову его 10 раз (используя Fiddler), я ожидаю, что все 10 вызовов вернутся через ~ 2 секунды. Однако призывы возвращаются после 2,4,8... 20 секунд, соответственно.
Что блокирует его одновременное выполнение? Как это исправить?
Регулярно ли контроллеры ведут себя так же, как контроллеры web-api?
Ответы
Ответ 1
То, что вы описываете, соответствует поведению по умолчанию для состояния сеанса ASP.NET и может быть разрешено путем его отключения в web.config.
Доступ к состоянию сеанса ASP.NET является исключительным для каждого сеанса, а это означает, что, если два разных пользователя выполняют параллельные запросы, доступ к каждому отдельному сеансу предоставляется одновременно. Однако, если два одновременных запроса сделаны для одного и того же сеанса (с использованием того же значения SessionID), первый запрос получает эксклюзивный доступ к информации о сеансе. Второй запрос выполняется только после завершения первого запроса. (Второй сеанс также может получить доступ, если исключительная блокировка информации освобождается, потому что первый запрос превышает тайм-аут блокировки.) Если значение EnableSessionState в директиве @страницы установлено в ReadOnly, запрос для чтения только для чтения информация сеанса не приводит к исключительной блокировке данных сеанса. Однако для запросов на чтение только для данных сеанса может потребоваться дождаться блокировки, установленной с помощью запроса на чтение и запись для очистки данных сеанса.
Источник: Обзор состояния сеанса ASP.NET
Ответ 2
Я не думаю, что я отвечаю на ваш вопрос, но то, что я хотел бы написать здесь, слишком велико для комментария.
Сначала ASP.NET Web API не имеет ничего общего с состоянием сеанса. Фактически, если сеанс должен использоваться с веб-API, он должен быть явно включен.
Теперь у меня такой же точный контроллер API, как вы, и я его размещаю в IIS. Если я делаю параллельные запросы, он выполняет запросы параллельно и не последовательно. Вот как я тестировал Fiddler.
Сначала я сделал GET API и дождался 200 кода состояния (# 1 в левой панели Fiddler). Затем я выбрал # 1 и нажал U, чтобы воспроизвести тот же запрос безоговорочно 9 раз. При этом у меня есть 10 запросов в левой панели (от # 1 до # 10). Затем я выбрал все 10 из них и нажал R, чтобы повторно передать все десять запросов параллельно. Затем я выбрал запросы с 11 по 20 в левой панели и перешел на вкладку "Временная шкала". Я вижу этот график.
PS. Я тестировал веб-API, работающий локально, BTW.
![enter image description here]()
Затем я захотел зарегистрировать запрос метки времени, полученный методом действия. Итак, я изменил метод действия, чтобы вернуть строку, подобную этой.
public string Get()
{
string ts = DateTime.Now.ToString("mm:ss.fff");
Thread.Sleep(2000);
return ts;
}
Я получил следующее.
00:43.795
00:43.795
00:45.812
00:44.517
00:43.795
00:43.795
00:45.515
00:43.795
00:43.795
00:43.795
Для меня это означает, что все запросы выполняются параллельно.
Ответ 3
Посмотрите на этот вопрос, который относится к вашей проблеме:
Выполняются ли все веб-запросы параллельно и обрабатываются асинхронно?
В нем указано, что:
Служба webApi по умолчанию выполняет все входящие запросы в параллельно, но только если текущие множественные запросы (при определенном время) происходило из разных сессий. То есть, если один клиент отправит несколько одновременных запросов на сервер, все они будут выполняется последовательно и не будет выполняться одновременно.
Чтобы решить эту проблему, вы можете использовать методы async, как описано здесь.
Как правило, вам нужно объявить свой метод как асинхронный, например:
public async Task<MyObj> GetObj()
Ответ 4
Попробуйте использовать это вместо:
public async Task<string> Tester()
{
await Task.Delay(2000);
return "OK";
}
Посмотрите на это, чтобы узнать разницу между Task.Delay и Thread.Sleep, которая блокирует http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx
Ответ 5
Возможно, вы включили Session State
для веб-Api. Веб-интерфейс по умолчанию остается безрезультатным и не имеет сеанса. Проверьте раздел global.asax Application_AuthenticateRequest (здесь я включаю состояние сеанса для Web Api). Найдите, где вы включили свое состояние сеанса, и установите его в режиме только для чтения, чтобы разрешить parallelism веб-методы, используя состояние сеанса. См. Этот вопрос, который аналогичен: Служба веб-API. Как сделать запросы на сервере выполняемыми одновременно
Ищите что-то вроде этого:
HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
Измените его так:
HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);