Асинхронные действия в ASP.NET MVC 4

У меня есть синхронный вызов, который мне нужно преобразовать в асинхронный, я использую ключевые слова async / await, но он возвращается только после завершения задачи, что мне нужно сделать, это вернуть результаты в пользовательский интерфейс один за другим.

Сценарий состоит в том, что у меня есть список задач, отображаемый для пользователя после аутентификации, однако я хотел бы, чтобы задача загружалась по одной после того, как они были извлечены из БД, вот мой actionResult, который объединяет критерии поиска для предварительного -фильтровать задачи:

public async Task<ActionResult> Index(string searchTerm = null, int page = 1)
{
    Shared.InitialiseCriteria(SearchCriteria);
    SearchCriteria.DepartmentID = DepartmentID;
    SearchCriteria.PageSize = 15;
    SearchCriteria.FreeText = searchTerm;

    var model = await DoStuff(SearchCriteria);

        if (Request.IsAjaxRequest())
        {
            return PartialView("_ConversationList", model);
        }
    return View(model);

 }

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

private async Task<Result> DoStuff(CSearchCriteria SearchCriteria)
{

   return GetConversations(SearchCriteria);
}

person user2711252    schedule 16.12.2013    source источник
comment
Не могли бы вы объяснить, что именно вы ожидаете, и что происходит на самом деле?   -  person sinelaw    schedule 16.12.2013
comment
Я хотел бы, чтобы задачи, найденные в БД, загружались в частичное представление одну за другой, чтобы пользователь не появлялся на экране загрузки, в настоящий момент для загрузки всего четырех задач требуется около 10 секунд. При необходимости я могу предоставить дополнительную информацию ...   -  person user2711252    schedule 17.12.2013


Ответы (2)


Единственная цель асинхронного контроллера в ASP.NET MVC - освободить поток IIS для управления некоторыми другими запросами во время выполнения асинхронной операции. С точки зрения вызывающего абонента это то же самое, как если бы вы использовали контроллер синхронизации.

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

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

person Oleksandr Kobylianskyi    schedule 16.12.2013
comment
+1. У меня есть сообщение в блоге, в котором объясняется, что async не изменить протокол HTTP. - person Stephen Cleary; 16.12.2013
comment
@Alex, спасибо за ваш ответ, не могли бы вы посоветовать, как я могу достичь желаемого результата. Я также пробовал использовать потоки, но не знаю, как обновить / обновить мое представление индекса после того, как первая задача была получена из БД. - person user2711252; 17.12.2013
comment
Я обновил ответ своим мнением, как это сделать. - person Oleksandr Kobylianskyi; 17.12.2013

Здесь есть пара проблем:

  • Как заставить ASP.NET начать возвращать данные, как только каждый элемент станет доступен,
  • Как координировать работу клиента и сервера, чтобы клиент знал, что доступен новый элемент (т.е. чтобы он мог анализировать каждый элемент в ответе отдельно или чтобы он мог запрашивать дополнительные данные, если вы ищете `` тянуть '')

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

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

person sinelaw    schedule 17.12.2013