Добавить обновление хода выполнения в реальном времени на медленную страницу в asp.net

#c# #asp.net #asp.net-ajax

#c# #asp.net #asp.net-ajax

Вопрос:

Я пытаюсь добавить отчет о ходе выполнения в реальном времени в мое приложение c # / asp.net 4.0 для страницы с медленной загрузкой. Я посмотрел на элементы управления UpdatePanel и UpdateProgress Ajax, но я не думаю, что они подходят.

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

Порядок действий был бы следующим: 1. пользователь нажимает кнопку для запуска 2. вызовите метод 1 3. когда метод 1 завершится, пользователь увидит «Метод 1 выполнен» 3. вызовите метод 2 и т.д.

Кто-нибудь может помочь с этим?

Ответ №1:

Такого рода асинхронное выполнение может быть сложным в реализации. Несколько решений, которые приходят мне в голову:

Полностью асинхронный без AJAX:

  1. Используйте кнопку «Нажимает», отправляет страницу.
  2. Сервер генерирует GUID для задачи и создает запись в вашей базе данных. Это может включать:

    • Guid (идентификатор)
    • Флаг состояния / перечисление
    • время начала.
  3. Сервер создает поток для обработки задачи и передает идентификатор Guid.

  4. Сервер возвращает идентификатор GUID вместе с сообщением «Работает …»
  5. Через n секунд / миллисекунд / insert-time-span-здесь браузер снова публикует страницу, включая команду «GetStatus» и идентификатор GUID.
  6. Сервер проверяет флаг состояния в базе данных на основе GUID.
  7. Сервер возвращает сообщение о состоянии на основе записи в базе данных («Шаг 2 …», «Все еще работает» или что-то еще подходящее)
  8. Переходите к шагу (5), пока статус, возвращаемый с сервера, не укажет, что процесс завершен.

В потоке, созданном на шаге (3):

  1. Запуск потока
  2. Считывать текущее состояние из записи базы данных
  3. Выполните следующий шаг на основе этого статуса
  4. Обновите статус базы данных, чтобы указать, что она готова к выполнению следующего шага, или установите флаг ошибки.
  5. Подождите несколько миллисекунд, чтобы не блокировать приложение (может быть ненужным — я не уверен, как потоки взаимодействуют в IIS)
  6. Выполняйте цикл до (2), пока все не будет сделано.
  7. Поток завершается.

Вот пример простого создания потока с помощью лямбда-выражения.

 (new Thread(
    () => {
        DoLongRunningWork();
    }
) { Name = "Long Running Work Thread"
    ,
    Priority = ThreadPriority.BelowNormal 
    }).Start();
  

Синхронный

Проще, но может вызвать некоторые проблемы с производительностью:

  1. Пользователь отправляет форму «Начать».
  2. Сервер записывает «Запуск …» в поток ответов и сбрасывает поток. Я думаю, это должно вернуть текст клиенту, но я не пробовал это годами.
  3. Сервер выполняет первый шаг.
  4. Сервер записывает статус в поток ответов и сбрасывает.
  5. Переходите к шагу (3) до завершения.

По сути, страница поддерживает соединение открытым до завершения задачи, а периодическая очистка выходных данных предотвращает истечение времени ожидания клиента. Это может привести к проблемам с тайм-аутами и т.д., И ваша конфигурация сервера (буферизация вывода и т.д.) Может быть проблемой.

Фоновая задача

Аналогично первому асинхронному подходу:

  1. Пользователь нажимает «Пуск»
  2. Сервер добавляет строку в базу данных, которая идентифицирует выполняемую задачу, извлекает идентификатор и возвращает его клиенту.
  3. Создайте запланированную задачу (скрипт, службу Windows и т.д.), Которая опрашивает таблицу, выполняет нужные задачи и обновляет статус по мере выполнения.
  4. Клиент периодически повторно отправляет форму с идентификатором базы данных. Сервер проверяет идентификатор по базе данных и возвращает сообщение о статусе (может содержать информацию о предыдущих шагах, таких как время выполнения, ETA и т.д.)
  5. Клиент переходит к (4), пока задача не будет завершена или не будут выдаваться ошибки.

Разница между этим и первым подходом заключается в том, что поток находится в отдельном процессе вместо IIS.

Конечно, у каждого подхода есть свои проблемы, и может быть более простой способ сделать это.

Комментарии:

1. Спасибо, я думаю, что ваш полностью асинхронный подход без AJAX является лучшим. Я уже настраивал фоновые задачи раньше и обнаружил, что они в лучшем случае ненадежны.

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