Расширяемость узла службы рабочих процессов
платформа .NET Framework 4.6.1 предоставляет WorkflowServiceHost класс для размещения служб рабочих процессов. Этот класс используется при размещении служб рабочих процессов в управляемом приложении или службе Windows. Этот класс также используется при размещении службы рабочего процесса в службах IIS или службе активации Windows (WAS). Класс WorkflowServiceHost обеспечивает точки расширения, которые дают возможность добавлять пользовательские расширения, изменять неактивное поведение и размещать рабочие процессы, не относящиеся к службе (то есть те, которые не используют обмен сообщениями).
Расширения размещения службы рабочего процесса
Класс WorkflowServiceHost содержит свойство WorkflowExtensions типа WorkflowInstanceExtensionManager, методы которого позволяют добавлять расширения к WorkflowServiceHost. Метод Add используется для добавления расширения в каждый из экземпляров. Указанный делегат вызывается для создания нового расширения при создании экземпляра службы рабочего процесса или его загрузке из хранилища сохраняемости. Метод Add используется для добавления расширения для каждого узла службы рабочего процесса, один экземпляр расширения совместно используется всеми экземплярами службы рабочего процесса.
Реакция на необработанные исключения
Поведение WorkflowUnhandledExceptionBehavior позволяет задать действие, которое должно быть выполнено в случае, если в службе рабочего процесса появляется необработанное исключение. Свойство Action определяет одно из следующих значений WorkflowUnhandledExceptionAction.
Abandon - аварийно завершает работу экземпляра службы рабочего процесса.
AbandonAndSuspend - выполняет откат до последнего сохраненного состояния и приостанавливает экземпляр службы рабочего процесса. Это происходит только в случае, если рабочий процесс уже хотя бы раз был сохранен. В противном случае экземпляр рабочего процесса аварийно завершается.
Cancel - отменяет экземпляр.
Terminate - завершает работу экземпляра.
Это поведение может быть настроено в коде, как показано в следующем примере.
host.Description.Behaviors.Add(new WorkflowUnhandledExceptionBehavior { Action = WorkflowUnhandledExceptionAction.Abandon });
Кроме того, его можно настроить в файле конфигурации, как показано в следующем примере.
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<workflowUnhandledExceptionBehavior action="Abandon" />
</behavior>
</serviceBehaviors>
</behaviors>
Размещение рабочих процессов, не относящихся к службе
Объект WorkflowServiceHost может быть использован для размещения рабочих процессов, не относящихся к службе, а также рабочих процессов, которые либо не начинают работу с действия Receive, либо не используют обмен сообщениями. Службы рабочих процессов, как правило, начинают работу с действия Receive. Когда WorkflowServiceHost получает сообщение для службы рабочего процесса, создается новый экземпляр службы рабочего процесса (если он не работает и не сохранен). Если рабочий процесс не начал работу с действия Receive, он не не может быть запущен отправкой сообщения, поскольку отсутствует действие, которое может принять это сообщение. Чтобы разместить рабочий процесс, не являющийся службой, создайте класс, наследующий WorkflowHostingEndpoint, и переопределите в нем методы OnGetInstanceId, OnGetCreationContext и OnResolveBookmark. Переопределите метод OnGetInstanceId, если необходимо задать определенный идентификатор экземпляра. Переопределите метод OnGetCreationContext для создания контекста создания рабочего процесса или заполните экземпляр из существующего WorkflowCreationContext. Переопределите метод OnResolveBookmark, если необходимо вручную извлекать закладку из входящего сообщения. При переопределении этого метода в его тексте необходимо вызвать метод SendResponse, чтобы ответить на сообщение, отправленное конечной точкой WorkflowHostingEndpoint. Если этого не сделать, предел MaxConcurrentCalls может быть превышен. В двусторонних контрактах пользователь может столкнуться с ошибкой при вызове метода SendResponse, связанной с тем, что клиент не получил ответ. В односторонних контрактах может возникнуть ситуация, когда ошибка, связанная с тем, что метод SendResponse не вызван, будет обнаружена только после превышения предела MaxConcurrentCalls, когда уже слишком поздно. Чтобы создать новый экземпляр рабочего процесса, отличного от службы, объявите контракт службы, определяющий операцию, которая создает новый экземпляр. Операция создания должна принимать строку IDictionary<, объект> для передачи всех необходимых параметров рабочего процесса. Этот контракт неявным образом реализуется классом, производным от WorkflowHostingEndpoint. При размещении рабочего процесса добавьте к узлу экземпляр класса, производного от WorkflowHostingEndpoint, вызвав метод AddServiceEndpoint, а затем вызовите метод Open. Чтобы создать экземпляр рабочего процесса, создайте фабрику ChannelFactory<TChannel> для типа контракта службы и вызовите метод CreateChannel. Затем можно вызвать операцию создания, определенную в контракте службы.