mvc async ждет кликов по ссылке, дождитесь завершения задачи

У меня есть веб-сайт MVC, где я пытаюсь вызвать метод с помощью async. Мой код выглядит следующим образом:

Просмотры

 <a href="#" class="submit-download" data-id="24589">Submit Download</a>

    $(document).on('click', '.submit-download', function (evt) {
        var submit_url = '/SubmitDownloads/24589; 

        $.ajax({
            type: 'POST',
            url: submit_url,
            success: function (data) {
                if (data.Item1)
                        location.reload();

            }
        });

    });

Контроллер

    [HttpPost]
    public async Task<JsonResult> SubmitDownloads(int id)
    {
        var respository = new WorkflowRepository();
        var result = await respository.SubmitAsync(id);
        return Json(result, JsonRequestBehavior.AllowGet);
    }

Метод репозитория

    //db service call which will take much longer time
    public async Task<Tuple<bool, string>> SubmitAsync(id)
    {
        //long running method here
         await Task.Delay(20000);
         return new Tuple<bool, string>(true, "done with " + id);

    }

Когда пользователь нажимает ссылку «Отправить загрузку» в представлениях, он выполняет всю функцию быстро, как и предполагалось, и страница становится отзывчивой, как прокручиваемая, меню отображается нормально. Но когда я нажимаю на любую ссылку на странице, она ожидает завершения всей операции (20 секунд), а затем перенаправляет на соответствующий URL-адрес.

Если я изменю Task.Delay на 50 секунд, нажатие ссылки займет 50 секунд для перенаправления.

Не могли бы вы рассказать мне, что мне здесь не хватает?


person sarojanand    schedule 23.02.2015    source источник
comment
Что у вас случилось?   -  person Yuval Itzchakov    schedule 23.02.2015


Ответы (1)


Но когда я нажимаю на любую ссылку на странице, она ожидает завершения всей операции (20 секунд), а затем перенаправляет на соответствующий URL-адрес.

Асинхронные методы контроллера не делают асинхронным HTTP-взаимодействие, только асинхронным взаимодействием веб-сервера с веб-приложением. Идея состоит в том, что веб-сервер большого объема может высвободить потоки для обслуживания других запросов, в то время как длительные запросы делают свое дело.

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

person David    schedule 23.02.2015
comment
есть ли способ поместить это в фоновый режим? Кажется, что страница разбилась, но не отображается сообщение об ошибке. - person sarojanand; 23.02.2015
comment
@sarojanand: Если загрузка страницы занимает много времени, я полагаю, вы захотите исправить то, что вызывает это. Возможно, код на стороне сервера может порождать отдельный поток для выполнения длительной задачи, или, возможно, веб-приложение может помещать информацию о задаче в очередь в базе данных, а совершенно отдельный процесс (например, служба Windows) может отслеживать эту базу данных и выполнять длительные задачи отдельно? (Обычно это то, что я делаю.) Ответы на веб-страницы - не лучшее место для размещения вещей, на выполнение которых уходит много времени. - person David; 23.02.2015
comment
Дэвид, я понимаю, о чем вы говорите. Сервисный код в порядке, просто он должен выполнять много операций ввода-вывода, а затем вычислять, это занимает 10-30 секунд на основе данных. Так что мы ничего не можем сделать для его оптимизации. Вот почему мы думаем сделать наш пользовательский интерфейс более отзывчивым с помощью Задач. - person sarojanand; 23.02.2015
comment
@sarojanand: использование задач разгружает операции в асинхронный контекст, но, как вы видите, это не обязательно делает пользовательский интерфейс более отзывчивым. Особенно в веб-приложении, где пользовательский интерфейс по дизайну должен ждать завершения работы сервера. (Поскольку сервер буквально отвечает пользовательским интерфейсом.) Основное правило - не выполнять длительные задачи в запросе веб-приложения. Выгрузите их в другое место, например в отдельный поток или процесс. Выполняя длительные задачи, встроенные в веб-приложение, которое заставляет конечного пользователя ждать завершения этих задач. - person David; 23.02.2015