State Machine WF: проблемы с завершением рабочего процесса - PullRequest
2 голосов
/ 03 апреля 2010

У нас есть рабочий процесс конечного автомата для поддержания состояния приложения, отправленного пользователем. Одна из проблем, с которыми я сталкиваюсь, связана с прекращением рабочего процесса. В одном из штатов у меня была ошибка. Когда приложение достигло этого состояния, оно выдало исключение, и в результате было вызвано событие завершения рабочего процесса, и конкретный экземпляр рабочего процесса был удален из базы данных постоянства. Поэтому я больше не могу загружать этот экземпляр рабочего процесса. Я бы надеялся, что если в одном из состояний возникнет ошибка, будет сгенерировано исключение (чтобы мы знали, в чем проблема), но весь экземпляр рабочего процесса не должен исчезнуть. Может ли действие обработчика ошибок гарантировать, что рабочий процесс не прерывается. Кроме того, есть ли способ, когда вызывается событие завершения, экземпляры не удаляются из постоянного хранилища.

Спасибо за любую помощь / предложения.

Ответы [ 3 ]

2 голосов
/ 12 ноября 2010

Когда в рабочий процесс создается исключение, оно будет эффективно «всплывать» через предков действия, пока оно не будет либо:

  1. Обрабатывается действием обработчика ошибок
  2. Достигает корневого действия (т. Е. Самого рабочего процесса), после чего рабочий процесс прекращается.

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

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

Один последний совет. Когда рабочий процесс завершается, исключение, вызвавшее завершение, отправляется в прослушиватели событий как свойство Exception объекта WorkflowTerminationEventArgs. Я бы абсолютно порекомендовал иметь какой-нибудь механизм протоколирования, чтобы поймать это и вывести его куда-нибудь, чтобы в будущем, если по какой-то причине вы столкнулись с ошибками, их было намного легче отследить.

0 голосов
/ 22 апреля 2016

Я использую SqlWorkflowPersistence, в качестве исправления для этого я сделал следующее:

В БД «WorkflowPersistence» у нас есть SP «InsertInstanceState», который удаляет экземпляр.Я прокомментировал код, который удаляет экземпляр.

Похоже, он работает, НО я не уверен, что это правильный путь.

Ниже показана часть SP, которую я изменил.

IF
@status=1 OR @status=3          
    BEGIN      

/* DELETE FROM [dbo].[InstanceState] WHERE uidInstanceID=@uidInstanceID AND ((ownerID = @ownerID AND ownedUntil>=@now) 
 OR (ownerID IS NULL AND @ownerID IS NULL ))          
*/
    END  
0 голосов
/ 01 февраля 2011

Я создал пользовательскую службу персистентности рабочего процесса SQL, которая предотвращает фактическое завершение рабочего процесса - тем самым оставляя рабочий процесс в предыдущем состоянии до перехода, вызвавшего ошибку:

public class CustomSqlWorkflowPersistenceService : SqlWorkflowPersistenceService
    {
        public CustomSqlWorkflowPersistenceService (string connectionString) : base(connectionString)
        {
        }

        public CustomSqlWorkflowPersistenceService (NameValueCollection parameters) : base(parameters)
        {
        }

        public CustomSqlWorkflowPersistenceService (string connectionString, bool unloadOnIdle, TimeSpan instanceOwnershipDuration, TimeSpan loadingInterval) : base(connectionString, unloadOnIdle, instanceOwnershipDuration, loadingInterval)
        {
        }

        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            WorkflowStatus workflowStatus = GetWorkflowStatus(rootActivity);
            if (workflowStatus == WorkflowStatus.Terminated)
            {
                string workflowError = GetSuspendOrTerminateInfo(rootActivity);
                if (!string.IsNullOrEmpty(workflowError))
                {
                    string error = string.Format("Workflow terminated, forcing an abort! {0}", workflowError);
                    throw new Exception(error);
                }
            }
            base.SaveWorkflowInstanceState(rootActivity, unlock);
        }
    }

Очевидно, что это будет боль, если вы захотите заставить WF завершить работу, но я уверен, что вы можете обойти это.

...