Как вы измеряете прогресс вызова веб-службы?

У меня есть веб-сервис ASP.NET, который выполняет тяжелую работу, например, над некоторыми файловыми операциями, или генерирует листы Excel из нескольких отчетов. Я не хочу, чтобы меня блокировали, вызывая этот веб-сервис, поэтому я хочу сделать вызов веб-сервиса асинхронным. Кроме того, я хочу вызвать этот веб-сервис с веб-страницы и хочу какой-то механизм, который позволит мне продолжать опрашивать сервер, чтобы я мог показать на экране какой-либо индикатор прогресса, например, количество файлов, которые были обработаны. Обратите внимание, что я не хочу получать уведомления о завершении вызова веб-метода, скорее, я хочу получить статус в реальном времени. Как мне это сделать?

6 ответов

Решение

Напишите на сервере отдельный метод, который вы можете запросить, передав идентификатор запланированного задания и возвращающий приблизительное значение от 0 до 100 (или от 0,0 до 1,0, или что-то еще) от того, как далеко оно продвинуто.

Например, в REST-стиле вы можете сделать запрос GET http://yourserver.com/app/jobstatus/4133/ который вернул бы простое '52' как text/plain, Тогда вам просто нужно запросить это каждые (секунды? Две секунды? Десять секунд?), Чтобы увидеть, как далеко это продвинуто.

То, как вы на самом деле выполняете мониторинг на бэкэнде, во многом зависит от того, каков ваш процесс и как он работает.

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

Позволяет что-то подобное в вашем клиенте:

//...
private localhost.MyWebServiceService _myWebService = new localhost.MyWebServiceService ();
_myWebService.processDelegate += ProgressUpdate;
_myWebService.CallHeavyMethod();
//...

private void ProgressUpdate(object sender, ProgressEventArgs e)
{
  double progress = ((double)e.ProcessedSize / (double)e.TotalSize) * 100.00;
  //Show Progress...
}

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

Попробуйте вместо этого расширения SOAP. Он реализует управляемую событиями модель. См. Добавление индикатора выполнения в клиентское приложение веб-службы на MSDN.

Самый простой способ - это обновить веб-службу в поле базы данных по мере выполнения вызова, а затем создать веб-службу, которая запрашивает это поле и возвращает значение.

Пусть начальный вызов веб-службы "Генерация отчета" создаст задачу в некотором пуле задач и вернет вызывающей стороне идентификатор задачи.

Затем предоставьте другой метод, который возвращает "процент выполненного" для заданного идентификатора задачи.

Предоставьте третий метод, который возвращает фактический результат для выполненной задачи.

Сделайте веб-сервис для возврата своего рода идентификатора задачи или идентификатора сеанса. Сделайте другой веб-метод для запроса с этим идентификатором, который возвращает необходимую информацию (% завершение, список файлов, что угодно). Опросить этот метод на некотором интервале от клиента.

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

РЕДАКТИРОВАТЬ: я только что видел другой аналогичный ответ, и комментарий к нему. Комментатор прав - вы можете использовать таблицу в памяти, чтобы избежать операций с диском, но все же используя отдельный сервер БД.

Другие вопросы по тегам