Condividi tramite


WorkflowPersistenceService.SaveWorkflowInstanceState Metodo

Definizione

Se implementato in una classe derivata, salva lo stato dell'istanza del flusso di lavoro in un archivio dati.

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)

Parametri

rootActivity
Activity

Attività radice dell'istanza del flusso di lavoro.

unlock
Boolean

true se l'istanza del flusso di lavoro non deve essere bloccata; false se l'istanza del flusso di lavoro deve essere bloccata.

Esempio

Nell'esempio seguente viene illustrata un'implementazione del metodo SaveWorkflowInstanceState. Questo esempio è tratto dall'esempio SDK Custom Persistence Service nel file FilePersistenceService.cs. Per altre informazioni, vedere Esempio di servizio di persistenza personalizzata.

// 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

Commenti

È necessario chiamare uno dei metodi Save di overload per serializzare rootActivity in un Stream. È quindi possibile scegliere anche di elaborare Stream prima di scriverlo nell'archivio dati. Tuttavia, quando il motore di runtime del flusso di lavoro chiama LoadWorkflowInstanceState, è necessario ripristinare una copia identica dell'attività radice. Se non è possibile salvare lo stato dell'istanza del flusso di lavoro nell'archivio dati, è necessario generare un'eccezione PersistenceException con un messaggio di errore adatto.

Il motore di runtime del flusso di lavoro implementa la semantica di blocco per limitare l'accesso allo stato di un'istanza del flusso di lavoro salvato nell'archivio dati. L'accesso può essere eseguito dai servizi di persistenza che sono in esecuzione in più host e che puntano allo stesso archivio dati. La semantica di blocco è progettata per impedire il caricamento della stessa istanza del flusso di lavoro in memoria contemporaneamente a servizi di persistenza in esecuzione in due runtime del flusso di lavoro diversi. A seconda del tipo di ambiente supportato dal servizio di persistenza, è possibile scegliere se supportare o meno questa funzionalità. Se si sceglie di supportare la semantica di blocco della fase di esecuzione e un servizio di persistenza tenta di salvare uno stato dell'istanza del flusso di lavoro precedentemente bloccato da un altro servizio di persistenza, è necessario generare un'eccezione WorkflowOwnershipException. Se unlock è true, è necessario sbloccare l'accesso allo stato dell'istanza del flusso di lavoro dopo averlo salvato.

LoadWorkflowInstanceState accetta il Guid dell'istanza del flusso di lavoro come parametro. Di conseguenza, è necessario salvare questo Guid. È anche possibile utilizzare questo Guid per associare l'istanza del flusso di lavoro agli stati salvati degli ambiti completati. Questa operazione è necessaria perché deve essere possibile contrassegnare questi ambiti completati come non necessari quando l'istanza del flusso di lavoro viene completata.

Il motore di runtime del flusso di lavoro chiama SaveWorkflowInstanceState un'ultima volta quando l'istanza del flusso di lavoro viene completata o terminata. Di conseguenza, se GetWorkflowStatus è uguale a Completed o Terminated, è possibile eliminare senza problemi l'istanza del flusso di lavoro e tutti i relativi ambiti completati dall'archivio dati. In alternativa, è possibile sottoscrivere gli eventi WorkflowCompleted o WorkflowTerminated per determinare quando è possibile eliminare senza problemi i record associati all'istanza del flusso di lavoro. Il momento in cui i record vengono effettivamente eliminati dall'archivio dati dipende dall'implementazione.

Se si implementa un servizio di persistenza che utilizza un archivio durevole, per mantenere la coerenza con lo stato interno del motore di runtime del flusso di lavoro, è necessario partecipare all'inclusione in batch delle transazioni del flusso di lavoro per rinviare l'effettiva scrittura nell'archivio durevole fino a un punto di commit del flusso di lavoro. Per partecipare all'inclusione in batch, aggiungere un elemento di lavoro alla proprietà WorkBatch che rappresenta le modifiche in sospeso all'archivio durevole e implementare l'interfaccia IPendingWork nel servizio di persistenza.

Si applica a