SharePoint 2010. Длительные операции с обновляемым статусом

Часть 1. SPLongOperation снаружи
Часть 2. SPLongOperation изнутри
Часть 3. SPLongOperation. Request timed out
Часть 4. Длительные операции с обновляемым статусом

В SharePoint 2010 есть класс SPStatefulLongOperation, который позволяет реализовать выполнение длительных операций с обновляемым статусом.

Сам класс унаследован от SPLongOperation и работает аналогично. В описании механизма работы класса SPLongOperation я писал, что трюк, заставляющий браузер ожидать выполнения операции заключается в отсутствии закрывающегося тега body. В отличие от своего родителя, класс SPStatefulLongOperation каждую секунду дописывает строку состояния в тело страницы. За это отвечает метод UpdateProgress:

  1. private void UpdateProgress(object state)
  2. {
  3.     SPLongOperationState state2 = state as SPLongOperationState;
  4.     string status = null;
  5.     if (state2 != null)
  6.     {
  7.         status = state2.Status;
  8.     }
  9.     if (string.IsNullOrEmpty(status))
  10.     {
  11.         status = "<!-- -->";
  12.     }
  13.     HttpContext.Current.Response.Write(status);
  14.     HttpContext.Current.Response.Flush();
  15. }

Во время выполнения операции пользователь видит примерно вот такой блок (в случае, если версия интерфейса равна 4):

Так как в Response мы можем только дописывать, но никак не изменять уже переданную информацию, то лучшим сценарием, на мой взгляд, здесь является передача клиентской стороне блока javascript-кода, который будет изменять текст в LeadingHTML и TrailingHTML.

Небольшой пример

Вот небольшой пример использования этого класса:

  1. SPStatefulLongOperation.Begin(
  2.     "<span id='leadingHTML'>Что-то происходит</span>",
  3.     "<span id='trailingHTML'>Все только началось</span>",
  4.     op =>
  5.     {
  6.         op.Run(opState =>
  7.         {
  8.             // Инициализируем пустой статус
  9.             opState.Status = string.Empty;
  10.             // Выполняем операцию
  11.             DoSomething();
  12.             // Меняем статус
  13.             opState.Status = string.Format(
  14.                     "<script type='text/javascript'>" +
  15.                     "document.all.item('leadingHTML').innerText = '{0}';" +
  16.                     "document.all.item('trailingHTML').innerText = '{1}';" +
  17.                     "</script>",
  18.                     "Что-то уже сделано",
  19.                     "Откиньтесь на спинку кресла");
  20.             // Выполняем еще какую-нибудь операцию
  21.             DoSomething2();
  22.         });
  23.         // При вызове метода End просто передаем URL для редиректа
  24.         op.End("http://blog.vitalyzhukov.ru");
  25.     });

В результате будут исполнены два метода (DoSomething и DoSomething2). Перед выполнением второго метода статус операции будет изменен, что дает возможность уведомить пользователя о текущем состоянии.


Поделиться

Коментарии