Поделиться через


WorkflowPersistenceService.SaveWorkflowInstanceState Метод

Определение

При реализации в производном классе сохраняет состояние экземпляра рабочего процесса в хранилище данных.

protected public:
 abstract void SaveWorkflowInstanceState(System::Workflow::ComponentModel::Activity ^ rootActivity, bool unlock);
protected internal abstract void SaveWorkflowInstanceState (System.Workflow.ComponentModel.Activity rootActivity, bool unlock);
abstract member SaveWorkflowInstanceState : System.Workflow.ComponentModel.Activity * bool -> unit
Protected Friend MustOverride Sub SaveWorkflowInstanceState (rootActivity As Activity, unlock As Boolean)

Параметры

rootActivity
Activity

Корневое действие экземпляра рабочего процесса.

unlock
Boolean

true, если экземпляр рабочего процесса не должен быть заблокирован; false, если экземпляр рабочего процесса должен быть заблокирован.

Примеры

В следующем примере показана реализация метода SaveWorkflowInstanceState. Данный пример кода является частью примера «Custom Persistence Service» из файла FilePersistenceService.cs. Дополнительные сведения см. в разделе Пример пользовательской службы сохраняемости.

// Save the workflow instance state at the point of persistence with option of locking the instance state if it is shared
// across multiple runtimes or multiple phase instance updates
protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
{
    // Save the workflow
    Guid contextGuid = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);
    Console.WriteLine("Saving instance: {0}\n", contextGuid);
    SerializeToFile(
        WorkflowPersistenceService.GetDefaultSerializedForm(rootActivity), contextGuid);

    // See when the next timer (Delay activity) for this workflow will expire
    TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty);
    TimerEventSubscription subscription = timers.Peek();
    if (subscription != null)
    {
        // Set a system timer to automatically reload this workflow when its next timer expires
        TimerCallback callback = new TimerCallback(ReloadWorkflow);
        TimeSpan timeDifference = subscription.ExpiresAt - DateTime.UtcNow;
        System.Threading.Timer timer = new System.Threading.Timer(
            callback,
            subscription.WorkflowInstanceId,
            timeDifference < TimeSpan.Zero ? TimeSpan.Zero : timeDifference,
            new TimeSpan(-1));
    }
}
' Save the workflow instance state at the point of persistence with option of locking the instance state if it is shared
' across multiple runtimes or multiple phase instance updates
Protected Overrides Sub SaveWorkflowInstanceState(ByVal rootActivity As System.Workflow.ComponentModel.Activity, ByVal unlock As Boolean)
    Dim contextGuid As Guid = CType(rootActivity.GetValue(Activity.ActivityContextGuidProperty), Guid)
    Console.WriteLine("Saving instance: 0}" + vbLf, contextGuid)
    SerializeToFile( _
        WorkflowPersistenceService.GetDefaultSerializedForm(rootActivity), contextGuid)

    ' See when the next timer (Delay activity) for this workflow will expire
    Dim timers As TimerEventSubscriptionCollection = CType(rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty), TimerEventSubscriptionCollection)
    Dim subscription As TimerEventSubscription = timers.Peek()
    If subscription IsNot Nothing Then
        ' Set a system timer to automatically reload this workflow when it's next timer expires
        Dim timeDifference As TimeSpan = subscription.ExpiresAt - DateTime.UtcNow
        Dim callback As TimerCallback = New TimerCallback(AddressOf ReloadWorkflow)
        Dim timer As New System.Threading.Timer( _
            callback, _
            subscription.WorkflowInstanceId, _
            CType(IIf(timeDifference < TimeSpan.Zero, TimeSpan.Zero, timeDifference), TimeSpan), _
            New TimeSpan(-1))
    End If
End Sub

Комментарии

Необходимо вызвать один из перегруженных методов Save для сериализации rootActivity в Stream. Затем можно выбрать дополнительную обработку Stream перед записью в хранилище данных. Однако при вызове LoadWorkflowInstanceState подсистемой среды выполнения рабочих процессов необходимо восстановить идентичную копию корневого действия. Если состояние экземпляра рабочего процесса невозможно сохранить в хранилище данных, необходимо вызвать исключение PersistenceException с соответствующим сообщением об ошибке.

Подсистема среды выполнения рабочих процессов обеспечивает семантику блокировки для ограничения доступа к состоянию экземпляра рабочего процесса, сохраненного в хранилище данных. К нему можно получить доступ с помощью служб постоянного хранения, выполняемых в разных основных приложениях и указывающих на одно хранилище данных. Семантика блокировки разработана, чтобы предотвратить службы постоянного хранения, выполняемых в двух разных средах выполнения рабочих процессов, от одновременной загрузки одного экземпляра рабочего процесса в память. В зависимости от типа среды, для поддержки которой разработана служба постоянного хранения, можно выбрать, поддерживать ли эту функциональную возможность. При выборе поддержки семантики блокировки среды выполнения, если служба постоянного хранения пытается сохранить экземпляр рабочего процесса, который ранее был заблокирован другой службой постоянного хранения, необходимо вызвать исключение WorkflowOwnershipException. Если для unlock задано значение true, необходимо разблокировать доступ к состоянию экземпляра рабочего процесса после его сохранения.

LoadWorkflowInstanceState принимает Guid экземпляра рабочего процесса в качестве параметра. Поэтому необходимо сохранить Guid. Также можно использовать этот тип Guid, чтобы связать экземпляр рабочего процесса с сохраненными состояниями завершенных областей. Это необходимо сделать, поскольку необходимо иметь возможность пометить эти завершенные области в качестве ненужных при завершении экземпляра рабочего процесса.

Подсистема среды выполнения рабочих процессов вызывает SaveWorkflowInstanceState в последний раз при завершении или прерывании экземпляра рабочего процесса. Поэтому если GetWorkflowStatus равно Completed или Terminated, можно безопасно удалить экземпляр рабочего процесса и все связанные завершенные области из хранилища данных. В качестве альтернативы можно подписаться на события WorkflowCompleted или WorkflowTerminated, чтобы определить, когда можно безопасно удалить записи, связанные с экземпляром рабочего процесса. Фактическое удаление записей из хранилища данных зависит от реализации.

При реализации службы постоянного хранения, использующей постоянное хранилище, для поддержки целостности с внутренним состоянием подсистемы среды выполнения рабочих процессов необходимо принять участие в пакетировании транзакции рабочего процесса, чтобы отложить фактическую запись в постоянное хранилище до точки фиксации рабочего процесса. Для принятия участия в пакетировании добавьте рабочий элемент, представляющий ожидающие изменения, в постоянное хранилище в свойство WorkBatch и реализуйте интерфейс IPendingWork в службе постоянного хранения.

Применяется к