#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:
- Используйте кнопку «Нажимает», отправляет страницу.
-
Сервер генерирует GUID для задачи и создает запись в вашей базе данных. Это может включать:
- Guid (идентификатор)
- Флаг состояния / перечисление
- время начала.
-
Сервер создает поток для обработки задачи и передает идентификатор Guid.
- Сервер возвращает идентификатор GUID вместе с сообщением «Работает …»
- Через n секунд / миллисекунд / insert-time-span-здесь браузер снова публикует страницу, включая команду «GetStatus» и идентификатор GUID.
- Сервер проверяет флаг состояния в базе данных на основе GUID.
- Сервер возвращает сообщение о состоянии на основе записи в базе данных («Шаг 2 …», «Все еще работает» или что-то еще подходящее)
- Переходите к шагу (5), пока статус, возвращаемый с сервера, не укажет, что процесс завершен.
В потоке, созданном на шаге (3):
- Запуск потока
- Считывать текущее состояние из записи базы данных
- Выполните следующий шаг на основе этого статуса
- Обновите статус базы данных, чтобы указать, что она готова к выполнению следующего шага, или установите флаг ошибки.
- Подождите несколько миллисекунд, чтобы не блокировать приложение (может быть ненужным — я не уверен, как потоки взаимодействуют в IIS)
- Выполняйте цикл до (2), пока все не будет сделано.
- Поток завершается.
Вот пример простого создания потока с помощью лямбда-выражения.
(new Thread(
() => {
DoLongRunningWork();
}
) { Name = "Long Running Work Thread"
,
Priority = ThreadPriority.BelowNormal
}).Start();
Синхронный
Проще, но может вызвать некоторые проблемы с производительностью:
- Пользователь отправляет форму «Начать».
- Сервер записывает «Запуск …» в поток ответов и сбрасывает поток. Я думаю, это должно вернуть текст клиенту, но я не пробовал это годами.
- Сервер выполняет первый шаг.
- Сервер записывает статус в поток ответов и сбрасывает.
- Переходите к шагу (3) до завершения.
По сути, страница поддерживает соединение открытым до завершения задачи, а периодическая очистка выходных данных предотвращает истечение времени ожидания клиента. Это может привести к проблемам с тайм-аутами и т.д., И ваша конфигурация сервера (буферизация вывода и т.д.) Может быть проблемой.
Фоновая задача
Аналогично первому асинхронному подходу:
- Пользователь нажимает «Пуск»
- Сервер добавляет строку в базу данных, которая идентифицирует выполняемую задачу, извлекает идентификатор и возвращает его клиенту.
- Создайте запланированную задачу (скрипт, службу Windows и т.д.), Которая опрашивает таблицу, выполняет нужные задачи и обновляет статус по мере выполнения.
- Клиент периодически повторно отправляет форму с идентификатором базы данных. Сервер проверяет идентификатор по базе данных и возвращает сообщение о статусе (может содержать информацию о предыдущих шагах, таких как время выполнения, ETA и т.д.)
- Клиент переходит к (4), пока задача не будет завершена или не будут выдаваться ошибки.
Разница между этим и первым подходом заключается в том, что поток находится в отдельном процессе вместо IIS.
Конечно, у каждого подхода есть свои проблемы, и может быть более простой способ сделать это.
Комментарии:
1. Спасибо, я думаю, что ваш полностью асинхронный подход без AJAX является лучшим. Я уже настраивал фоновые задачи раньше и обнаружил, что они в лучшем случае ненадежны.
2. Дайте мне знать, как это происходит — у меня не было времени посмотреть, что происходит с потоком, когда он создается со страницы или контроллера. Я видел другие ссылки на это, которые указывают, что это должно работать.