Постоянство рабочего процесса и закладки как переключение рабочего процесса

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

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

  • приостановлено пользователем (в любое время) и позже возобновлено из закладки / точки, в которой она была приостановлена ​​(например, пользователь заметил, что внешняя система не работает, и он хочет приостановить рабочий процесс на время).
  • в случае необработанного исключения мы можем возобновить выполнение с последней закладки / момента времени
  • остановка узла WorkflowApplication может произойти в любое время, и мы можем возобновить выполнение с последней закладки / момента времени

Я работал в течение нескольких дней с постоянным рабочим процессом, но я не уверен, смогу ли я достичь своей цели с его помощью. Зачем?

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

Можете ли вы посоветовать мне, это закладки рабочего процесса, путь сюда?

Я вижу свет в неблокирующих закладках, но не могу их сохранить и возобновить позже. Не могли бы вы дать мне несколько советов, как сохранить неблокирующую закладку для последующего возобновления?

Редактировать:

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

В идеале было бы здорово иметь возможность выполнить context.RequestPersist(callback) от NativeActivityContext, однако этот метод является внутренним (и все, что находится внутри него, не видно снаружи оригинальной сборки.

2 ответа

Решение

Вот что я пришел с:

  • Неблокирующие закладки не являются опцией. Хотя неблокирующая закладка не препятствует завершению создания, но также не приводит к тому, что экземпляр рабочего процесса становится бездействующим - это означает, что он не будет сохранен. Неблокирующие закладки отбрасываются после завершения действия (которое его создало). Эта закладка может быть возобновлена, только если создание действия еще не завершено.
  • С помощью PersistOnCloseAttribute это не вариант, потому что я использую WF4 и этот атрибут только.NET 3.x WF.
  • Блокирующие закладки не могут быть использованы, потому что они блокируют выполнение рабочего процесса, что нежелательно.

Решение заключается в использовании Persist активность в каждой сделанной на заказ деятельности (должна расширяться NativeActivity который может запланировать деятельность ребенка):

//class field
Activity childActivity = new Persist();

Чтобы это работало, его нужно добавить в метаданные как ImplmentationChild:

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
     base.CacheMetadata(metadata);
     metadata.AddImplementationChild(this.childActivity);
}

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

protected override void Execute(NativeActivityContext context)
{
    //...
    context.ScheduleActivity((Activity)this.childActivity);
}

Чтобы сохранить рабочий процесс после необработанного исключения, этот фрагмент кода должен быть добавлен в WorkflowApplication:

 application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
 {
      return UnhandledExceptionAction.Abort;
 };

* возврат из Execute Метод не обязательно означает, что действие "завершено" - т.е. внутри действия есть блокировка закладок (см. недостатки ниже).

Есть несколько недостатков этого решения:

  • Решение сохраняет только одно состояние рабочего процесса (последнее состояние).
  • Упорство может произойти только после завершения деятельности. Это означает, что постоянное / возобновление не может быть сделано с середины действия.
  • Он не работает с параллельными циклами / последовательностями - действия из параллельного цикла / последовательности сохраняются после завершения всего параллельного процесса. Он работает правильно с обычными циклами / последовательностями.
  • Блокирующие закладки имеют огромное влияние на это решение (если они создаются при создании действия или в других дочерних действиях по созданию действия). Они приводят к тому, что действие не завершается, даже если возвращен метод Execute. В конце концов, Persist выполнится (либо после завершения действия, либо до перехода в состояние ожидания).

Если я правильно понимаю ваш вопрос, то у вас есть требования ниже.

  1. Постоянство и восстановление рабочего процесса.
  2. Пользователь может приостановить и возобновить.
  3. В случае каких-либо исключений рабочий процесс сохраняется и возобновляется со следующего действия.

Вы можете подойти, используя следующие шаги.

  1. Вы можете использовать сервис WF + WCF для выполнения и размещения вашего рабочего процесса.
  2. Добавьте постоянство и отслеживание с базой данных, такой как сервер Sql, если вы используете oracle, то можете использовать Devart.
  3. Настройте ControlEnpont для приостановки и возобновления.
  4. Мудро используйте try/ Catch и сохраняемость для обработки исключений.

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