Introduzione all'hosting di Windows Workflow Foundation

Moustafa Khalil Ahmed
Program Manager
Microsoft Corporation

Agosto 2006

Relativo a:
Windows Workflow Foundation
Microsoft .NET Framework 2.0
Microsoft .NET Framework 3.0

Riepilogo: Una panoramica sull'utilizzo di un'applicazione di hosting di Windows Workflow Foundation (WF) per gestire e monitorare i flussi di lavoro in esecuzione, nonché informazioni sui servizi di runtime e le relative implementazioni predefinite. Ai lettori viene richiesta una certa dimestichezza con Microsoft .NET Framework, C# e il modello di programmazione di WF. (16 pagine stampate)

Sommario

Introduzione
Gestione del ciclo di vita delle istanze del flusso di lavoro
Gestibilità e monitoraggio
Affidabilità ed elevata disponibilità
Servizi di runtime di base
Conclusioni
Ulteriori informazioni

Introduzione

Questo articolo è diretto agli sviluppatori che utilizzano Windows Workflow Foundation (WF) per aiutarli a comprendere le diverse opzioni disponibili per attivare le applicazioni per la gestione e il monitoraggio delle istanze del flusso di lavoro in esecuzione. Questo articolo si rivolge a lettori con una comprensione almeno basilare di Microsoft .NET Framework, C# e WF.

WF comprende una libreria di attività e un framework, un motore di runtime e componenti di servizi di runtime da eseguire nel processo dell'applicazione host. I flussi di lavoro vengono creati come insiemi di attività eseguite dal motore di runtime. Il motore di runtime deve essere eseguito in un processo dell'applicazione host. Nella seguente figura è illustrato il modo in cui i flussi di lavoro, le attività e il motore di runtime del flusso di lavoro vengono inclusi nel processo con un'applicazione host.

Figura 1. Processo host di Windows Workflow Foundation

WF fornisce un motore di runtime, responsabile dell'esecuzione del flusso di lavoro e della gestione dello stato. Il runtime di WF può essere incluso in qualsiasi processo .NET, inclusi ASP.NET, servizi Windows, applicazioni console e applicazioni Windows Form. Lo sviluppatore è responsabile della scrittura del processo host durante la creazione di un'applicazione che supporti i flussi di lavoro. I servizi di runtime del processo host forniscono funzionalità aggiuntive al motore di runtime quando gestisce l'esecuzione dei flussi di lavoro.

Esistono diversi problemi da tenere in considerazione quando si implementa un'applicazione host per WF. In questo articolo viene fornita una panoramica delle modalità di gestione e monitoraggio dei flussi di lavoro da parte dell'applicazione host, nonché un riepilogo dei servizi di runtime di base e delle relative implementazioni predefinite.

Gestione del ciclo di vita delle istanze del flusso di lavoro

WF fornisce attività predefinite e metodi relativi a operazioni di controllo nella classe WorkflowInstance per la gestione degli stati e del ciclo di vita del flusso di lavoro. Nella sezione Gestione del ciclo di vita delle istanze del flusso di lavoro vengono descritti i diversi eventi di runtime specifici delle istanze del flusso di lavoro, nonché le transizioni tra tali eventi e le relazioni con gli stati del flusso di lavoro.

Punti di persistenza

I flussi di lavoro sono spesso associati a lunghi tempi di esecuzione e di inattività dovuti all'attesa di input da parte dell'utente o di altri sistemi. Considerata la scarsa praticità nel mantenere in memoria i flussi di lavoro inattivi, si consiglia di rendere persistente lo stato dell'istanza del flusso di lavoro in un supporto di archiviazione finché non si verifica l'evento atteso per il flusso di lavoro. Inoltre, il salvataggio dello stato dell'istanza del flusso di lavoro consente di riprendere il flusso di lavoro dal punto in cui è stato interrotto nel caso in cui si verifichi un errore durante il processo.

Nella figura 2 è illustrato l'utilizzo dei punti di persistenza per riprendere le istanze del flusso di lavoro in esecuzione.

Figura 2. Utilizzo dei punti di persistenza per riprendere le istanze del flusso di lavoro in esecuzione

Se lo stato di un'istanza del flusso di lavoro viene mantenuto nel punto B e si verifica un errore nel punto C, l'applicazione è in grado di riprendere tale istanza dal punto B senza perdere il lavoro svolto tra i punti A e B. Se tuttavia non è disponibile un servizio di persistenza oppure se lo stato dell'istanza del flusso di lavoro non viene mantenuto, il lavoro svolto dal punto A al punto B viene perso.

Se un servizio WorkflowPersistenceService è disponibile (ossia, è stato aggiunto all'istanza WorkflowRuntime), il motore di runtime del flusso di lavoro utilizza questo servizio per rendere persistente lo stato dell'istanza del flusso di lavoro in un supporto di archiviazione. Ciò può verificarsi nei seguenti punti:

  • Al completamento delle attività contrassegnate con PersistOnCloseAttribute (ad esempio, le attività dell'ambito delle transazioni)

  • Prima del completamento di un'istanza del flusso di lavoro

  • Prima della terminazione di un'istanza del flusso di lavoro

  • Quando il flusso di lavoro diventa inattivo

  • Quando vengono chiamati WorkflowInstance.Unload o WorkflowInstance.TryUnload

Il motore di runtime di WF chiama il metodo SaveWorkflowInstanceState() in WorkflowPersistenceService per salvare lo stato dell'istanza del flusso di lavoro. Se necessario, chiama il metodo LoadWorkflowInstanceState() per recuperare lo stato persistente dell'istanza del flusso di lavoro. Il runtime del flusso di lavoro gestisce tutta la semantica relativa alla tempistica per l'esecuzione della persistenza, mentre i servizi di persistenza sono responsabili dell'effettivo salvataggio e caricamento dell'istanza del flusso di lavoro. Gli stati dell'attività e l'ID dell'istanza del flusso di lavoro vengono serializzati e salvati nell'archivio di persistenza. Inoltre, tutte le informazioni aggiuntive per il riavvio dell'esecuzione dell'istanza del flusso di lavoro (ad esempio, le code) vengono incluse nello stato serializzato e salvato.

Eventi dell'istanza del flusso di lavoro

Un'istanza del flusso di lavoro può trovarsi in uno dei seguenti cinque stati: Creato, In esecuzione, Sospeso, Completato e Terminato. Nel corso del ciclo di vita dell'istanza del flusso di lavoro si verificano 13 eventi associati ai flussi di lavoro. Tali eventi possono indicare una transizione verso un altro stato: ad esempio, l'evento WorkflowCompleted indica il passaggio dallo stato In esecuzione allo stato Completato. Alcuni eventi non indicano tale transizione: ad esempio, l'evento WorkflowPersisted indica che l'istanza è persistente ma si trova ancora nello stato In esecuzione. Di questi 13 eventi, 11 vengono comunicati all'applicazione host tramite eventi di runtime e di eventi del flusso di lavoro di rilevamento. Due eventi, Changed ed Exception, vengono comunicati all'applicazione host solo tramite gli eventi del flusso di lavoro di rilevamento.

WF fornisce metodi relativi a operazioni di controllo nella classe WorkflowInstance per attivare le applicazioni host per la gestione del ciclo di vita del flusso di lavoro. Inoltre, un'applicazione è in grado di impostare criteri per la gestione del ciclo di vita del flusso di lavoro. Ad esempio, un'applicazione può disporre di criteri di scaricamento grazie ai quali viene indicato al motore di WF in che modo scaricare l'istanza del flusso di lavoro. WF fornisce attività predefinite in grado di influire sullo stato dell'istanza del flusso di lavoro. Ad esempio, le attività SuspendActivity e TerminateActivity possono essere utilizzate, rispettivamente, per sospendere e terminare l'istanza del flusso di lavoro. Nelle seguenti sezioni vengono illustrati vari eventi specifici dell'istanza del flusso di lavoro generati dal runtime del flusso di lavoro per comunicare gli eventi e le transizioni di stato dell'istanza del flusso di lavoro.

WorkflowAborted

Un'istanza del flusso di lavoro viene considerata interrotta quando il motore di runtime del flusso di lavoro elimina l'istanza in memoria. Le applicazioni host possono interrompere l'istanza del flusso di lavoro chiamando WorkflowInstance.Abort(). Le istanze del flusso di lavoro interrotte possono essere recuperate dall'ultimo punto di persistenza chiamando WorkflowInstance.Resume(). L'interruzione di un'istanza del flusso di lavoro viene utilizzata in situazioni estreme nelle quali un'applicazione ignora tutto il lavoro svolto dall'ultimo punto di persistenza fino alla chiamata di WorkflowInstance.Abort().

WorkflowCompleted

Un'istanza del flusso di lavoro viene completata quando termina la relativa esecuzione. A questo punto, l'applicazione host è in grado di esaminare le code per cercare messaggi e altri eventi non utilizzati dall'istanza del flusso di lavoro.

WorkflowCreated

Un flusso di lavoro viene creato al termine della creazione dell'istanza, ma prima che venga avviata l'esecuzione delle attività. L'istanza del flusso di lavoro viene creata chiamando uno dei numerosi metodi di overload WorkflowRuntime.CreateWorkflow().

WorkflowIdled

L'istanza del flusso di lavoro è inattiva quando è in attesa di un evento esterno (timer, messaggio o altri eventi personalizzati) per proseguire l'esecuzione. Per salvare le risorse di sistema, è possibile utilizzare un'applicazione per impostare un criterio in base al quale scaricare l'istanza del flusso di lavoro dalla memoria quando è inattiva. Se l'applicazione host utilizza il servizio predefinito SqlWorkflowPersistenceService, è possibile impostare un flag UnloadOnIdle nel file di configurazione dell'applicazione per specificare che il motore di runtime di WF deve rendere persistente lo stato del flusso di lavoro quando l'istanza è inattiva.

WorkflowLoaded

L'evento WorkflowLoaded viene generato quando lo stato dell'istanza viene caricato nella memoria da un archivio di persistenza.

WorkflowPersisted

Quando il servizio predefinito SqlWorkflowPersistenceService o un servizio di persistenza personalizzato viene aggiunto all'istanza WorkflowRuntime, l'istanza del flusso di lavoro diviene persistente quando viene salvata nell'archivio di persistenza.

WorkflowResumed

L'istanza del flusso di lavoro viene recuperata quando WorkflowInstance.Resume() viene chiamato in un'istanza del flusso di lavoro sospesa o interrotta.

WorkflowStarted

L'evento WorkflowStarted viene generato quando viene chiamato WorkflowInstance.Start(). L'evento avviato dal flusso di lavoro viene generato prima che il motore di runtime del flusso di lavoro avvii l'esecuzione delle attività del flusso di lavoro.

WorkflowSuspended

La sospensione dell'istanza del flusso di lavoro viene eseguita tramite una chiamata WorkflowInstance.Suspend() o quando viene eseguita un'attività SuspendActivity. L'istanza del flusso di lavoro viene quindi a trovarsi in stato di sospensione.

WorkflowTerminated

La terminazione dell'istanza del flusso di lavoro viene eseguita tramite una chiamata a WorkflowInstance.Terminate(), quando viene eseguita un'attività TerminateActivity o quando si verifica un'eccezione non gestita nell'istanza del flusso di lavoro in esecuzione. Dopo che è stato generato questo evento, l'istanza del flusso di lavoro si trova in stato di terminazione.

WorkflowUnloaded

L'evento WorkflowUnloaded viene generato quando l'istanza del flusso di lavoro viene scaricata dalla memoria in un archivio di persistenza. Questa operazione viene eseguita sulla base dei criteri di persistenza oppure tramite una chiamata a WorkflowInstance.Unload() o WorkflowInstance.TryUnload().

Transizioni tra eventi dell'istanza del flusso di lavoro

Gli eventi dell'istanza del flusso di lavoro vengono comunicati all'host tramite eventi di runtime ed eventi del flusso di lavoro di rilevamento. L'applicazione host può sottoscrivere gli eventi di runtime o utilizzare un servizio di rilevamento per ottenere le notifiche. Gli eventi Exception e Changed vengono comunicati solo all'applicazione host tramite i servizi di rilevamento. Un evento Exception indica che si è verificata un'eccezione durante l'esecuzione dell'istanza del flusso di lavoro. Un evento Changed indica che l'istanza del flusso di lavoro è stata aggiornata dinamicamente durante l'esecuzione.

Nella figura 3 sono illustrate le transizioni tra i diversi eventi del flusso di lavoro e gli stati del flusso di lavoro.

Fare clic qui per ingrandire l'immagine

Figura 3. Transizioni tra eventi e stati del flusso di lavoro (fare clic sull'immagine per ingrandirla)

Se è attivato un servizio di persistenza, i punti di persistenza si verificano come indicato nella figura 3. Nei casi appropriati, tali applicazioni host visualizzano gli eventi WorkflowPersisted, WorkflowUnloaded e WorkflowLoaded. Se l'istanza del flusso di lavoro non è in memoria e il servizio di persistenza è attivato, qualsiasi operazione valida eseguita sull'istanza (Resume, Abort, Terminate e così via) causa il caricamento dell'istanza del flusso di lavoro seguito dal completamento della richiesta. Ad esempio, se si ha un'istanza del flusso di lavoro sospesa ma non scaricata e si chiama Resume, l'istanza viene prima caricata, quindi continua a generare l'evento Resumed come indicato nel diagramma.

Operazioni dell'istanza del flusso di lavoro

Come discusso in precedenza, la classe WorkflowInstance dispone di metodi per il controllo del ciclo di vita dell'istanza del flusso di lavoro. In questa sezione vengono descritti tali metodi.

WorkflowInstance.Start()

Avvia l'esecuzione dell'istanza del flusso di lavoro creata. WorkflowInstance.Start() causa la generazione dell'evento WorkflowStarted da parte del runtime del flusso di lavoro. L'istanza del flusso di lavoro si trova in stato In esecuzione. Viene generata un'eccezione InvalidOperationException se Start() viene chiamato in un'istanza del flusso di lavoro già avviata.

WorkflowInstance.Abort()

Interrompe l'istanza del flusso di lavoro. Se l'interruzione riesce, il runtime del flusso di lavoro genera un evento WorkflowAborted.

WorkflowInstance.Load()

Carica un'istanza del flusso di lavoro scaricata da un archivio di persistenza nella memoria. Viene quindi pianificata l'esecuzione dell'istanza dallo stato in cui si trovava prima di essere scaricata. Se il caricamento riesce, il runtime del flusso di lavoro genera un evento WorkflowLoaded.

WorkflowInstance.Resume()

Riprende (ossia, continua l'esecuzione di) un'istanza del flusso di lavoro sospesa o interrotta. Il runtime del flusso di lavoro genera l'evento WorkflowResumed appena prima che l'esecuzione dell'istanza del flusso di lavoro venga ripresa.

WorkflowInstance.Suspend()

Sospende l'esecuzione dell'istanza del flusso di lavoro. Se la chiamata a WorkflowInstance.Suspend() viene eseguita correttamente, il runtime del flusso di lavoro genera l'evento WorkflowSuspended.

WorkflowInstance.Terminate()

Termina l'istanza del flusso di lavoro ed elimina l'istanza del flusso di lavoro nella memoria. Il runtime del flusso di lavoro informa il servizio di persistenza registrato che l'istanza del flusso di lavoro è stata eliminata dalla memoria. Per SqlWorkflowPersistenceService, ciò significa che tutte le informazioni di stato per l'istanza del flusso di lavoro vengono eliminate dal database al termine dell'operazione. Non è possibile ricaricare l'istanza del flusso di lavoro da un punto di persistenza precedentemente archiviato. Se WorkflowInstance.Terminate() viene eseguito correttamente, il runtime del flusso di lavoro genera l'evento WorkflowTerminated.

WorkflowInstance.Unload()

Scarica l'istanza del flusso di lavoro dalla memoria all'archivio di persistenza. Il metodo WorkflowInstance.Unload() è sincrono e viene bloccato fino al completamento del lavoro in esecuzione oppure fino al termine di un ambito di transazione per garantire che lo scaricamento venga eseguito correttamente. Se WorkflowInstance.Unload() viene eseguito correttamente, il runtime del flusso di lavoro genera l'evento WorkflowUnloaded. Se Unload() viene chiamato quando non esiste alcun servizio di persistenza registrato, viene generata un'eccezione InvalidOperationException.

WorkflowInstance.TryUnload()

Diversamente da WorkflowInstance.Unload(), il metodo WorkflowInstance.TryUnload() non si blocca in attesa di poter scaricare il flusso di lavoro. WorkflowInstance.TryUnload() scarica l'istanza del flusso di lavoro dalla memoria all'archivio di persistenza e restituisce true quando l'istanza viene sospesa o è inattiva. In alternativa, la chiamata restituisce false. Se TryUnload() viene chiamato quando non esiste alcun servizio di persistenza registrato, viene generata un'eccezione InvalidOperationException.

Vedere Windows Foundation SDK per ulteriori informazioni sui diversi metodi di controllo di WorkflowInstance.

Gestibilità e monitoraggio

Le applicazioni che ospitano i flussi di lavoro sono responsabili della gestione e del monitoraggio dei flussi di lavoro ospitati ed eseguiti. WF fornisce supporto per diversi strumenti di gestibilità e monitoraggio. Ad esempio, WF offre funzionalità di analisi completa utilizzabili per il debug di basso livello, nonché un'infrastruttura di rilevamento per l'estrazione e il monitoraggio dei dati di flusso di lavoro.

In questa sezione viene discussa l'infrastruttura di gestibilità e monitoraggio e il suo utilizzo nelle applicazioni host.

Rilevamento

WF fornisce un'infrastruttura di rilevamento per acquisire eventi e dati relativi al flusso di lavoro, alle attività e agli utenti mentre sono in esecuzione le istanze del flusso di lavoro. Qualsiasi istanza di runtime del flusso di lavoro può essere associata a più servizi di rilevamento registrati o a nessuno. Le informazioni di rilevamento vengono inviate ai servizi di rilevamento registrati, che sono responsabili dell'archiviazione e dell'elaborazione delle informazioni in base alle esigenze dell'applicazione host. WF fornisce un servizio di rilevamento predefinito basato su SQL (SqlTrackingService) utilizzabile tramite un'applicazione host. Inoltre, gli sviluppatori di applicazioni host possono scrivere servizi di rilevamento personalizzati e utilizzarli per le applicazioni host.

È possibile utilizzare il rilevamento per esaminare la cronologia di esecuzione delle istanze del flusso di lavoro e determinare lo stato corrente delle istanze del flusso di lavoro in esecuzione nel sistema. Inoltre, il rilevamento fornisce informazioni utilizzabili insieme alla definizione del flusso di lavoro per determinare in anticipo i percorsi di esecuzione previsti delle istanze del flusso di lavoro in esecuzione nel sistema. WF fornisce un esempio di applicazione, Workflow Monitor Sample, che utilizza il servizio predefinito SqlTrackingService e i controlli di progettazione del flusso di lavoro per visualizzare le informazioni sullo stato del flusso di lavoro e delle attività relative ai flussi di lavoro completati e attualmente in esecuzione.

Per ulteriori informazioni sul monitoraggio dei flussi di lavoro tramite il rilevamento, vedere lo strumento SDK Workflow Monitor, disponibile nella sezione Application Samples/Workflow Monitor Sample. Per esempi su come creare un servizio di rilevamento personalizzato, vedere gli esempi ConsoleTrackingService Sample e File Tracking Service and Query Sample, disponibili nella sezione Technology Samples/Tracking. Per esempi di utilizzo del servizio predefinito SqlTrackingService, vedere Simple Tracking Sample e Query Using SQLTrackingService Sample, disponibili nella sezione Technology Samples/Trackingout-of-box.

Analisi e analisi completa

È possibile utilizzare le analisi per eseguire il monitoraggio dello stato dell'applicazione, nonché l'isolamento e la risoluzione dei problemi senza interferire con il sistema in esecuzione. In WF vengono utilizzate le API System.Diagnostics per analizzare le informazioni sul runtime del flusso di lavoro e l'esecuzione delle istanze del flusso di lavoro, comprese le informazioni di valutazione dell'insieme di regole. Per impostazione predefinita, le analisi sono disattivate, ma è possibile attivarle.

Inoltre, WF supporta funzionalità di analisi completa. Le funzionalità di analisi completa attivano i visualizzatori di analisi per visualizzare informazioni di analisi continua e le transizioni tra i vari componenti. Ciò semplifica il debug completo.

Se si utilizza un file di configurazione di un'applicazione, è necessario aggiungere i seguenti elementi per attivare l'analisi della registrazione per più spazi dei nomi WF:

        <system.diagnostics>
        <switches>
        <add name="System.Workflow LogToTraceListeners" value="1" />
        <add name="System.Workflow.Runtime" value="All" />
        <add name="System.Workflow.Runtime.Hosting" value="All" />
        <add name="System.Workflow.Runtime.Tracking" value="All" />
        <add name="System.Workflow.Activities" value="All" />
        <add name="System.Workflow.Activities.Rules" value="All" />
        </switches>
        </system.diagnostics>
      

Quando viene utilizzato LogToTraceListeners, WF enumera tutti i TraceListener creati all'interno dell'applicazione host e invia loro tutte le informazioni di registrazione. Le righe restanti dell'esempio consentono di specificare gli spazi dei nomi per acquisire le informazioni di registrazione, oltre alla quantità delle informazioni analizzate. I valori possibili dell'attributo comprendono All, Off, Critical, Error, Warning, Information e Verbose. Vedere l'SDK di WF per ulteriori informazioni sull'utilizzo degli attributi del valore.

Eventi di runtime del flusso di lavoro

Gli eventi di runtime vengono generati dal runtime del flusso di lavoro e forniscono all'applicazione host gli strumenti per gestire il ciclo di vita del runtime del flusso di lavoro e delle istanze del flusso di lavoro. I gestori eventi vengono definiti nella classe WorkflowRuntime e l'applicazione host deve sottoscrivere tali eventi per poterli utilizzare.

Gli eventi di runtime funzionano come un sistema di notifica semplificato quando è opportuno che l'applicazione host agisca su uno specifico evento piuttosto che memorizzare eventi e dati associati per l'inoltro di query. A tale scopo, invece, si consiglia di utilizzare l'infrastruttura di rilevamento.

Un'istanza WorkflowRuntime potrebbe eseguire più istanze del flusso di lavoro, ciascuna delle quali ha un proprio ciclo di vita. Pertanto, gli argomenti per gli eventi dell'istanza del flusso di lavoro contengono l'ID dell'istanza del flusso di lavoro e altre informazioni. Tali informazioni possono essere utilizzate per correlare l'evento all'istanza del flusso di lavoro che ne causa la generazione.

Nelle seguenti sezioni sono descritti gli eventi di runtime del flusso di lavoro disponibili.

WorkflowRuntime.ServiceExceptionNotHandled

Questo evento viene generato quando il thread appartenente al servizio genera un'eccezione. Un servizio derivato dalla classe WorkflowRuntimeService può chiamare il metodo RaiseServicesExceptionNotHandledEvent() per segnalare ai sottoscrittori dell'evento ServicesExceptionNotHandled che durante l'esecuzione di tale evento si è verificata un'eccezione che non è possibile gestire. I servizi predefiniti generano l'evento sulla base di queste condizioni. L'applicazione host può sottoscrivere l'evento per implementare un meccanismo di ripristino. L'argomento associato all'evento è ServicesExceptionNotHandledEventArgs.

WorkflowRuntime.Started

Questo evento viene generato all'avvio dell'istanza specificata di WorkflowRuntime. L'argomento associato all'evento è WorkflowRuntimeEventArgs.

WorkflowRuntime.Stopped

Questo evento viene generato al termine dell'istanza specificata di WorkflowRuntime. L'argomento associato all'evento è WorkflowRuntimeEventArgs.

Tabella 1. WorkflowInstanceEvents

Evento Descrizione Argomento evento
WorkflowAborted Generato quando l'istanza del flusso di lavoro viene interrotta. WorkflowEventArgs
WorkflowCompleted Generato quando l'istanza del flusso di lavoro viene completata. WorkflowCompletedEventArgs
WorkflowCreated Generato una volta completata l'istanza del flusso di lavoro, ma prima di elaborare le attività, ossia prima dell'esecuzione del flusso di lavoro. WorkflowEventArgs
WorkflowIdled Generato quando l'istanza del flusso di lavoro entra in uno stato di inattività, ossia quando l'istanza del flusso di lavoro è in attesa di un evento esterno (ad esempio, un timer, un messaggio e così via) per continuare l'esecuzione. WorkflowEventArgs
WorkflowLoaded Generato quando l'istanza del flusso di lavoro viene caricata in memoria, generalmente da un archivio di persistenza. WorkflowEventArgs
WorkflowPersisted Generato quando l'istanza del flusso di lavoro è persistente. WorkflowEventArgs
WorkflowResumed Generato quando l'istanza del flusso di lavoro viene recuperata, generalmente dallo stato di sospensione o di interruzione. WorkflowEventArgs
WorkflowStarted Generato quando viene avviata l'esecuzione dell'istanza del flusso di lavoro. WorkflowEventArgs
WorkflowSuspended Generato quando l'istanza del flusso di lavoro viene sospesa. WorkflowSuspendedEventArgs
WorkflowTerminated Generato quando l'istanza del flusso di lavoro viene terminata. WorkflowTerminatedEventArgs
WorkflowUnloaded Generato quando l'istanza del flusso di lavoro viene scaricata dalla memoria a un archivio di persistenza. WorkflowEventArgs

Vedere la precedente sezione dell'articolo "Gestione del ciclo di vita delle istanze del flusso di lavoro" per ulteriori informazioni sui diversi eventi e sul passaggio del flusso di lavoro nei vari stati.

Vedere gli esempi dell'SDK di Windows Workflow Foundation per informazioni su come utilizzare i vari eventi di runtime del flusso di lavoro.

Contatori delle prestazioni

È possibile monitorare le prestazioni del flusso di lavoro tramite lo strumento Prestazioni di Windows, costituito da due componenti: Monitor di sistema e Avvisi e registri di prestazioni. Con Avvisi e registri di prestazioni, è possibile configurare i contatori delle prestazioni per registrare i dati sulle prestazioni e impostare gli avvisi di sistema che segnalano quando il valore del contatore specificato è superiore o inferiore alla soglia definita.

WF fornisce un insieme di contatori delle prestazioni con l'oggetto prestazioni di WF che è possibile utilizzare per rilevare le prestazioni di un flusso di lavoro. Vedere la sezione relativa ai contatori delle prestazioni del flusso di lavoro nell'SDK di WF per un elenco completo di contatori delle prestazioni.

Per dettagli relativi a come aggiungere contatori delle prestazioni allo strumento Prestazioni, vedere il sito Web Microsoft TechNet.

Criterio di scaricamento

In un determinato momento, nei sistemi potrebbero essere simultaneamente in esecuzione migliaia di flussi di lavoro. Conservare tali flussi in memoria potrebbe risultare decisamente poco pratico. Per gestire meglio le risorse di un sistema, è possibile impostare un criterio di scaricamento che consenta di rendere persistenti gli stati del flusso di lavoro e scaricarli dalla memoria.

WF fornisce un criterio di scaricamento durante l'inattività se si utilizza il servizio di persistenza predefinito. Tale criterio è attivo quando si imposta la proprietà UnloadOnIdle sulla classe SqlWorkflowPersistenceService per specificare che il motore di runtime deve scaricare il flusso di lavoro quando non è attivo. Se l'applicazione host attiva SqlWorkflowPersistenceService tramite un file di configurazione, è possibile eseguire l'operazione impostando il flag UnloadOnIdle su true. Se SqlWorkflowPersistenceService è stato creato e attivato tramite codice, l'applicazione host deve creare tale flag tramite il costruttore SqlWorkflowPersistenceService (String, Boolean, TimeSpan, TimeSpan). L'applicazione host è in grado di implementare altri criteri di scaricamento complessi.

Inoltre, è possibile chiamare il metodo WorkflowInstance.Unload() per richiedere lo scaricamento di una specifica istanza del flusso di lavoro dalla memoria, rendendone lo stato persistente. L'applicazione host può quindi chiamare il metodo Load() sulle istanze per continuare l'esecuzione dall'ultimo punto di persistenza. Quando le istanze del flusso di lavoro vengono scaricate, viene generato l'evento di runtime WorkflowUnloaded.

Affidabilità ed elevata disponibilità

WF supporta gli host configurati come affidabili e a elevata disponibilità tramite il supporto per le seguenti tecnologie:

Clustering SQL

Servizi predefiniti basati su SQL per il supporto dell'installazione cluster. I servizi SQL predefiniti di WF offrono la possibilità di effettuare più tentativi quando si esegue il commit del batch su SQL Server. Pertanto, il supporto non è operativo nel caso di scenari di failover o di temporanea inaccessibilità dei server SQL. La logica dei tentativi può essere impostata su una qualsiasi combinazione basata sui seguenti servizi:

  • DefaultWorkflowCommitWorkBatchService

  • SharedConnectionWorkflowCommitWorkBatchService

  • SqlTrackingService

  • SqlWorkflowPersistenceService

Per impostazione predefinita, la logica dei tentativi è disattivata. Per utilizzarla nell'applicazione host, deve essere attivata in modo esplicito. Nelle applicazioni è possibile scegliere di attivare i tentativi in base al servizio o a tutti i servizi menzionati precedentemente. A questo scopo, impostare la proprietà EnableRetries delle classi dei servizi o tramite il file di configurazione. Con un file di configurazione, l'applicazione host è in grado di utilizzare un flag condiviso, EnableRetries, per impostare l'attivazione o la disattivazione dei tentativi in tutti i servizi interessati. Se la proprietà EnableRetries è impostata su un servizio, il valore da essa prodotto sovrascrive il valore del flag condiviso EnableRetries. I servizi di WF predefiniti basati su SQL eseguono un numero costante di tentativi, che non è configurabile. Tuttavia, le applicazioni possono regolare il timeout delle connessioni nella stringa delle connessioni dei servizi in modo da regolare parzialmente il tempo tra i tentativi.

Impostazione dei tentativi

Nel seguente esempio viene illustrato in che modo impostare EnableRetries per tutti i servizi predefiniti aggiungendo un parametro comune, EnableRetries, e impostandone il valore su True. Inoltre, viene mostrato come disattivare EnableRetries per SqlWorkflowPersistenceService aggiungendo un flag EnableRetries per il servizio e impostandolo su False.

        <WorkflowRuntime Name="SampleApplication" UnloadOnIdle="false">
        <CommonParameters>
        <add name="ConnectionString" 
value="Initial Catalog=WorkflowStore;Data Source=localhost;Integrated Security=SSPI;" />
        <add name="EnableRetries" value="True" />
        </CommonParameters>
        <Services>
        <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
        System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
        PublicKeyToken=31bf3856ad364e35" EnableRetries="False"  />
        </Services>
        </WorkflowRuntime>
      

In linea di massima, è consiglia di impostare in modo coerente i tentativi per tutti i servizi in modalità di attivazione o di disattivazione.

Si noti che la classe WorkflowCommitWorkBatchService è responsabile per i tentativi di commit di batch relativi ad attività non di tipo TransactionScopeActivity (punti di persistenza). La classe WorkflowCommitBatchService non è in grado di eseguire tentativi di commit di batch di lavoro per le attività TransactionScopeActivity. In questo caso, ciò dipende dal fatto che tale classe non avvia la transazione e, quindi, non ne è proprietaria. I tentativi di commit del batch di lavoro per le attività TransactionScopeActivity devono essere modellati nel flusso di lavoro. Questa operazione viene generalmente eseguita sotto forma di ciclo While e di gestore delle eccezioni fuori da TransactionScopeActivity.

I tentativi nel servizio predefinito SqlTrackingService, se eseguito in modalità non transazionale, e il servizio predefinito SqlWorkflowPersistenceService controllano il lavoro basato su SQL non relativo ai commit del batch di lavoro. Ciò comprende il controllo dei timer scaduti e il caricamento delle istanze del flusso di lavoro.

Bilanciamento del carico e scalabilità front-end

L'applicazione che ospita WF è responsabile della gestione degli scenari di bilanciamento del carico e di scalabilità front-end. WF fornisce supporto per il motore e i servizi predefiniti basati su SQL per attivare diverse istanze dell'applicazione host affinché facciano riferimento agli stessi database SQL di persistenza o di rilevamento.

Se si dispone di più applicazioni host connesse allo stesso archivio di persistenza, ciascuna di esse potrebbe caricare qualsiasi tipo di istanza del flusso di lavoro dal database. Il servizio predefinito di WF SqlWorkflowPersistenceService non supporta l'assegnazione dei tipi di flusso di lavoro o delle istanze da caricare su host specifici nel caso in cui condividano lo stesso archivio di persistenza. È necessario implementare un servizio di persistenza personalizzato se questo comportamento non soddisfa le esigenze dell'applicazione host.

Il motore di runtime di WF fornisce la semantica di blocco per il supporto di scenari di scalabilità front-end quando più applicazioni host utilizzano lo stesso archivio di persistenza. Questa semantica di blocco impedisce che le applicazioni carichino un'istanza del flusso di lavoro già caricata da un'altra applicazione. La classe WorkflowPersistenceService consente il supporto della funzionalità del motore di runtime del flusso di lavoro tramite un parametro del metodo SaveWorkflowInstanceState() che specifica se le informazioni sullo stato di un'istanza del flusso di lavoro debbano essere sbloccate nell'archivio dei dati e tramite il metodo UnlockWorkflowInstanceState() che consente di sbloccare le informazioni precedentemente bloccate. In un servizio di persistenza che implementi il blocco, una chiamata al metodo LoadWorkflowInstanceState() dovrebbe bloccare le informazioni sullo stato di un'istanza del flusso di lavoro.

Per ulteriori informazioni sulla semantica di blocco delle istanze del flusso di lavoro, vedere le sezioni relative ai servizi di persistenza del flusso di lavoro di Windows e alla creazione di servizi di persistenza personalizzati nella guida di programmazione di WF.

Servizi di runtime di base

Il motore di runtime di WF esegue i flussi di lavoro tramite i servizi di runtime. Grazie al modello di servizi di runtime, l'applicazione host dispone della flessibilità necessaria per fornire più servizi al motore di runtime di WF. In questa sezione vengono illustrati i servizi di runtime forniti da WF e le implementazioni predefinite di tali servizi.

Per ulteriori informazioni sulle implementazioni dei servizi di runtime, vedere le sezioni relative ai servizi di Windows Workflow Foundation e allo sviluppo dei servizi di Windows Workflow Foundation nella guida di programmazione di WF.

Il runtime di WF offre quattro servizi che dispongono di implementazioni predefinite. In alternativa, le applicazioni host possono implementare servizi personalizzati e fornirli al runtime del flusso di lavoro.

Servizi di transazione del flusso di lavoro

Lo scopo dei servizi di transazione del flusso di lavoro di Windows (WorkflowCommitWorkBatchService) consiste nell'attivazione di una logica personalizzata legata all'esecuzione di commit dei batch di lavoro (anche noti come punti di persistenza). Quando viene eseguito il commit di un batch di lavoro, il runtime richiama il servizio di transazione corrente e individua un delegato che esegua effettivamente il commit del batch di lavoro. Benché l'esecuzione del commit spetti comunque al runtime, l'introduzione di un servizio permette un certo grado di personalizzazione del processo di commit.

Il framework di WF non supporta l'importazione della transazione dall'esterno in un'istanza del flusso di lavoro. Gli unici tipi di transazioni di ambiente supportati da WorkflowCommitWorkBatchService sono quelle generate dall'istanza del flusso di lavoro. Le transazioni di ambiente generate dall'applicazione host che esegue il runtime del flusso di lavoro vengono rimosse temporaneamente dal thread corrente per ridurre gli effetti collaterali. Quando il flusso di lavoro diventa inattivo, la transazione di ambiente originale dell'applicazione host viene reinserita nel thread.

WF fornisce due implementazioni predefinite per i servizi di transazione: DefaultWorkflowCommitWorkBatchService e SharedConnectionWorkflowCommitWorkBatchService.

Il motore di runtime di WF richiede un servizio di transazione per il flusso di lavoro. Per impostazione predefinita, viene utilizzato DefaultWorkflowCommitWorkBatchService. L'applicazione host può scegliere di sostituire DefaultWorkflowSchedulerService con SharedConnectionDefaultWorkflowCommitWorkBatchService o con un servizio personalizzato.

DefaultWorkflowCommitWorkBatchService

Se non vengono aggiunti altri servizi di transazione, quando viene avviato il motore di runtime del flusso di lavoro, un'istanza di DefaultWorkflowCommitWorkBatchService viene creata e aggiunta a WorkflowRuntime. Questo servizio crea transazioni .NET Framework per ciascuna connessione al database. Ad esempio, le connessioni tra i servizi di rilevamento SQL e i servizi di persistenza SQL non vengono condivise. È possibile utilizzare questo servizio per il supporto delle transazioni necessarie per l'integrità dei dati nei flussi di lavoro.

SharedConnectionWorkflowCommitWorkBatchService

Questo servizio viene utilizzato per le transazioni dei database che utilizzano una connessione condivisa tra oggetti diversi. Per utilizzare questo servizio, l'applicazione host deve aggiungerlo a WorkflowRuntime tramite il metodo AddService o tramite il file di configurazione.

Servizi di pianificazione del flusso di lavoro

I servizi di pianificazione del flusso di lavoro consentono di gestire il modo in cui le istanze del flusso di lavoro vengono pianificate dal motore di runtime del flusso di lavoro, sia in modalità asincrona che in modalità sincrona manuale. WF fornisce due implementazioni predefinite per il servizio WorkflowSchedulerService: DefaultWorkflowSchedulerService e ManualWorkflowSchedulerService.

Il motore di runtime di WF richiede un servizio di pianificazione del flusso di lavoro per eseguire i flussi di lavoro. Per impostazione predefinita, viene utilizzato DefaultWorkflowSchedulerService. L'applicazione host può scegliere di sostituire DefaultWorkflowSchedulerService con ManualWorkflowSchedulerService o con un servizio personalizzato.

DefaultWorkflowSchedulerService

DefaultWorkflowSchedulerService crea e gestisce i thread che eseguono le istanze del flusso di lavoro in modalità asincrona nel motore di runtime del flusso di lavoro e comprende il supporto predefinito per l'accodamento di più istanze del flusso di lavoro nel pool di thread di runtime. Se non vengono aggiunti altri servizi di pianificazione del flusso di lavoro a WorkflowRuntime, per impostazione predefinita viene utilizzato il servizio DefaultWorkflowSchedulerService.

ManualWorkflowSchedulerService

ManualWorkflowSchedulerService viene utilizzato per l'esecuzione sincrona delle istanze del flusso di lavoro. Se viene utilizzato questo servizio, le istanze del flusso di lavoro vengono eseguite nel thread chiamante dall'applicazione host, bloccando pertanto l'esecuzione dell'applicazione host finché l'istanza del flusso di lavoro non diventa inattiva.

Servizi di persistenza del flusso di lavoro

I servizi di persistenza sono responsabili della memorizzazione e del recupero (caricamento e scaricamento) dello stato dell'istanza del flusso di lavoro. WF fornisce un'implementazione predefinita basata su SQL del servizio di persistenza: SqlWorkflowPersistenceService.

SqlWorkflowPersistenceService

Questa implementazione predefinita memorizza lo stato e le informazioni sul timer in SQL Server/MSDE. SqlWorkflowPersistenceService prende parte alle transazioni del flusso di lavoro e implementa il blocco dell'accesso. Inoltre, SqlWorkflowPersistenceService fornisce una funzionalità che consente di eseguire più tentativi quando il server SQL non è disponibile. Tale funzionalità può essere controllata impostando la proprietà EnableRetries del servizio. Per ulteriori informazioni su SqlWorkflowPersistenceService, vedere la guida di programmazione di WF.

Servizi di rilevamento del flusso di lavoro

I servizi di rilevamento gestiscono i profili di rilevamento e la memorizzazione delle informazioni di rilevamento. WF fornisce un'implementazione predefinita basata su SQL di un servizio di rilevamento implementato nella classe SqlTrackingService.

SqlTrackingService

Questa implementazione memorizza i profili e i dati di rilevamento in SQL Server/MSDE. Il servizio supporta le seguenti opzioni:

  • Prende parte alle transazioni del flusso di lavoro per impostazione predefinita; tale comportamento viene controllato dalla proprietà SqlTrackingService.IsTransactional.

  • Fornisce un meccanismo per utilizzare profili di rilevamento predefiniti per tutti i tipi o le associazioni di profili di rilevamento per i tipi o le istanze del flusso di lavoro.

  • Supporta la manutenzione dei dati tramite funzionalità di partizionamento in tempo reale e su richiesta. Le informazioni dettagliate sulla manutenzione dei dati sono disponibili nella sezione relativa alla manutenzione dei dati con SqlTrackingService della guida di programmazione di WF.

Inoltre, WF fornisce API SqlTrackingQuery da utilizzare per eseguire query dei dati di rilevamento memorizzati in SqlTrackingService. Per ulteriori informazioni su SqlTrackingService, vedere la guida di programmazione di WF.

Conclusioni

WF fornisce un motore di runtime e servizi per eseguire i flussi di lavoro e gestirne lo stato. Per ospitare i flussi di lavoro di WF, è necessario scrivere un'applicazione o un processo host. Tale applicazione host fornisce i vari servizi di runtime al motore di runtime del flusso di lavoro. I servizi di runtime di WF predefiniti sono progettati per gli scenari comuni. Tuttavia, se i servizi predefiniti non soddisfano le esigenze dell'applicazione host, è necessario implementare servizi personalizzati e fornirli al runtime del flusso di lavoro.

Inoltre, WF fornisce un'infrastruttura per la gestione e il monitoraggio delle istanze del flusso di lavoro in esecuzione e per il supporto delle applicazioni host configurate come affidabili e a elevata disponibilità. La scelta delle opzioni da utilizzare per le applicazioni host dipende dagli specifici scenari di hosting.

Ulteriori informazioni

Questo articolo, insieme alle seguenti risorse, consente agli sviluppatori che iniziano a lavorare sulla tecnologia del flusso di lavoro di inquadrarne gli aspetti chiave e diventare rapidamente produttivi utilizzandola.

 

Informazioni sull'autore
Moustafa Khalil Ahmed è Program Manager del team di WF presso Microsoft Corp., Redmond, WA. Dal suo arrivo in Microsoft nel 2000, ha collaborato allo sviluppo di diversi componenti per server e ha contribuito alla distribuzione di quattro prodotti per server, tra cui Microsoft BizTalk Server. Prima di lavorare alla Microsoft, Moustafa è stato Software Engineer, Business Analyst e Account Manager presso ITWorx, Il Cairo, Egitto.

Mostra: