Procedura: creare un partecipante del rilevamento personalizzato
Il rilevamento del flusso di lavoro fornisce la visibilità nello stato dell'esecuzione del flusso di lavoro. Il runtime del flusso di lavoro genera i record di rilevamento che descrivono gli eventi del ciclo di vita di flusso del lavoro, gli eventi del ciclo di vita delle attività, le riprese dei segnalibri e gli errori. Tali record di rilevamento vengono usati dai partecipanti del rilevamento. Windows Workflow Foundation (WF) viene fornito con un partecipante del rilevamento standard che scrive record di rilevamento come eventi ETW (Event Tracing for Windows). Se tale partecipante non soddisfa i propri requisiti, è anche possibile scrivere un partecipante del rilevamento personalizzato. In questo passaggio dell'esercitazione viene illustrato come creare un profilo di rilevamento e un partecipante di rilevamento personalizzati che acquisiscono l'output delle attività di WriteLine
per renderlo visibile all'utente.
Per creare un partecipante di rilevamento personalizzato
Fare clic con il pulsante destro del mouse su NumberGuessWorkflowHost in Esplora soluzioni e scegliere Aggiungi, Classe. Digitare
StatusTrackingParticipant
nella casella Nome e fare clic su Aggiungi.Aggiungere le seguenti istruzioni
using
(oImports
) nella parte superiore del file con le altre istruzioniusing
(oImports
).Imports System.Activities.Tracking Imports System.IO
using System.Activities.Tracking; using System.IO;
Modificare la classe
StatusTrackingParticipant
per fare in modo che erediti daTrackingParticipant
.Public Class StatusTrackingParticipant Inherits TrackingParticipant End Class
class StatusTrackingParticipant : TrackingParticipant { }
Aggiungere il seguente override del metodo
Track
. Esistono vari tipi di record di rilevamento. In questo caso, si usa l'output delle attività diWriteLine
contenute nei record di rilevamento delle attività. SeTrackingRecord
è unActivityTrackingRecord
di un'attivitàWriteLine
,Text
diWriteLine
viene aggiunto a un file denominato dopo l'elementoInstanceId
del flusso di lavoro. In questa esercitazione, il file viene salvato nella cartella corrente dell'applicazione host.Protected Overrides Sub Track(record As TrackingRecord, timeout As TimeSpan) Dim asr As ActivityStateRecord = TryCast(record, ActivityStateRecord) If Not asr Is Nothing Then If asr.State = ActivityStates.Executing And _ asr.Activity.TypeName = "System.Activities.Statements.WriteLine" Then 'Append the WriteLine output to the tracking 'file for this instance. Using writer As StreamWriter = File.AppendText(record.InstanceId.ToString()) writer.WriteLine(asr.Arguments("Text")) writer.Close() End Using End If End If End Sub
protected override void Track(TrackingRecord record, TimeSpan timeout) { ActivityStateRecord asr = record as ActivityStateRecord; if (asr != null) { if (asr.State == ActivityStates.Executing && asr.Activity.TypeName == "System.Activities.Statements.WriteLine") { // Append the WriteLine output to the tracking // file for this instance using (StreamWriter writer = File.AppendText(record.InstanceId.ToString())) { writer.WriteLine(asr.Arguments["Text"]); writer.Close(); } } } }
Se non è specificato alcun profilo di rilevamento, viene usato il profilo di rilevamento predefinito. Quando viene usato il profilo di rilevamento predefinito, i record di rilevamento vengono generati per tutti gli elementi
ActivityStates
. Dal momento che è necessario acquisire il testo solo una volta durante il ciclo di vita dell'attivitàWriteLine
, si estrae solo il testo dello statoActivityStates.Executing
. Nell'argomento Per creare il profilo di rilevamento e registrare il partecipante di rilevamento viene creato un profilo di rilevamento in cui si specifica che vengono generati solo record di rilevamento diWriteLine
ActivityStates.Executing
.
Per creare il profilo di rilevamento e registrare il partecipante di rilevamento
Fare clic con il pulsante destro del mouse su WorkflowHostForm in Esplora soluzioni, quindi scegliere Visualizza codice.
Aggiungere la seguente istruzione
using
(oImports
) nella parte superiore del file con le altre istruzioniusing
(oImports
).Imports System.Activities.Tracking
using System.Activities.Tracking;
Aggiungere il codice seguente a
ConfigureWorkflowApplication
immediatamente dopo il codice che aggiungeStringWriter
alle estensioni del flusso di lavoro e prima dei gestori del ciclo di vita del flusso di lavoro.'Add the custom tracking participant with a tracking profile 'that only emits tracking records for WriteLine activities. Dim query As New ActivityStateQuery() query.ActivityName = "WriteLine" query.States.Add(ActivityStates.Executing) query.Arguments.Add("Text") Dim profile As New TrackingProfile() profile.Queries.Add(query) Dim stp As New StatusTrackingParticipant() stp.TrackingProfile = profile wfApp.Extensions.Add(stp)
// Add the custom tracking participant with a tracking profile // that only emits tracking records for WriteLine activities. StatusTrackingParticipant stp = new StatusTrackingParticipant { TrackingProfile = new TrackingProfile { Queries = { new ActivityStateQuery { ActivityName = "WriteLine", States = { ActivityStates.Executing }, Arguments = { "Text" } } } } }; wfApp.Extensions.Add(stp);
Questo profilo di rilevamento specifica che vengono generati solo i record di stato dell'attività per le attività
WriteLine
nello statoExecuting
per il partecipante di rilevamento personalizzato.Dopo aver aggiunto il codice, l'inizio di
ConfigureWorkflowApplication
risulterà analogo al seguente esempio.Private Sub ConfigureWorkflowApplication(wfApp As WorkflowApplication) 'Configure the persistence store. wfApp.InstanceStore = store 'Add a StringWriter to the extensions. This captures the output 'from the WriteLine activities so we can display it in the form. Dim sw As New StringWriter() wfApp.Extensions.Add(sw) 'Add the custom tracking participant with a tracking profile 'that only emits tracking records for WriteLine activities. Dim query As New ActivityStateQuery() query.ActivityName = "WriteLine" query.States.Add(ActivityStates.Executing) query.Arguments.Add("Text") Dim profile As New TrackingProfile() profile.Queries.Add(query) Dim stp As New StatusTrackingParticipant() stp.TrackingProfile = profile wfApp.Extensions.Add(stp) 'Workflow lifecycle handlers...
private void ConfigureWorkflowApplication(WorkflowApplication wfApp) { // Configure the persistence store. wfApp.InstanceStore = store; // Add a StringWriter to the extensions. This captures the output // from the WriteLine activities so we can display it in the form. StringWriter sw = new StringWriter(); wfApp.Extensions.Add(sw); // Add the custom tracking participant with a tracking profile // that only emits tracking records for WriteLine activities. StatusTrackingParticipant stp = new StatusTrackingParticipant { TrackingProfile = new TrackingProfile { Queries = { new ActivityStateQuery { ActivityName = "WriteLine", States = { ActivityStates.Executing }, Arguments = { "Text" } } } } }; wfApp.Extensions.Add(stp); // Workflow lifecycle handlers...
Per visualizzare le informazioni di rilevamento
Fare clic con il pulsante destro del mouse su WorkflowHostForm in Esplora soluzioni, quindi scegliere Visualizza codice.
Nel gestore
InstanceId_SelectedIndexChanged
, aggiungere il codice seguente subito dopo il codice che cancella la finestra di stato.'If there is tracking data for this workflow, display it 'in the status window. If File.Exists(WorkflowInstanceId.ToString()) Then Dim status As String = File.ReadAllText(WorkflowInstanceId.ToString()) UpdateStatus(status) End If
// If there is tracking data for this workflow, display it // in the status window. if (File.Exists(WorkflowInstanceId.ToString())) { string status = File.ReadAllText(WorkflowInstanceId.ToString()); UpdateStatus(status); }
Quando viene selezionato un nuovo flusso di lavoro nell'elenco dei flusso di lavoro, i record di rilevamento del flusso di lavoro vengono caricati e visualizzati nella finestra di stato. Nell'esempio seguente viene mostrato il gestore
InstanceId_SelectedIndexChanged
completato.Private Sub InstanceId_SelectedIndexChanged(sender As Object, e As EventArgs) Handles InstanceId.SelectedIndexChanged If InstanceId.SelectedIndex = -1 Then Return End If 'Clear the status window. WorkflowStatus.Clear() 'If there is tracking data for this workflow, display it 'in the status window. If File.Exists(WorkflowInstanceId.ToString()) Then Dim status As String = File.ReadAllText(WorkflowInstanceId.ToString()) UpdateStatus(status) End If 'Get the workflow version and display it. 'If the workflow is just starting then this info will not 'be available in the persistence store so do not try and retrieve it. If Not WorkflowStarting Then Dim instance As WorkflowApplicationInstance = _ WorkflowApplication.GetInstance(WorkflowInstanceId, store) WorkflowVersion.Text = _ WorkflowVersionMap.GetIdentityDescription(instance.DefinitionIdentity) 'Unload the instance. instance.Abandon() End If End Sub
private void InstanceId_SelectedIndexChanged(object sender, EventArgs e) { if (InstanceId.SelectedIndex == -1) { return; } // Clear the status window. WorkflowStatus.Clear(); // If there is tracking data for this workflow, display it // in the status window. if (File.Exists(WorkflowInstanceId.ToString())) { string status = File.ReadAllText(WorkflowInstanceId.ToString()); UpdateStatus(status); } // Get the workflow version and display it. // If the workflow is just starting then this info will not // be available in the persistence store so do not try and retrieve it. if (!WorkflowStarting) { WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(this.WorkflowInstanceId, store); WorkflowVersion.Text = WorkflowVersionMap.GetIdentityDescription(instance.DefinitionIdentity); // Unload the instance. instance.Abandon(); } }
Per compilare ed eseguire l'applicazione
Premere CTRL+MAIUSC+B per compilare l'applicazione.
Premere CTRL+F5 per avviare l'applicazione.
Selezionare un intervallo per il gioco per determinare un numero e il tipo di flusso di lavoro da avviare, quindi fare clic su Nuova partita. Immettere un tentativo nella casella Guess, quindi fare clic su Vai per inviare il tentativo. Si noti che lo stato del flusso di lavoro viene visualizzato nella finestra di stato. Questo output viene acquisito dalle attività
WriteLine
. Passare a un altro flusso di lavoro selezionandone uno dalla casella combinata ID istanza flusso di lavoro. Lo stato del flusso di lavoro corrente viene rimosso. Passare di nuovo al flusso di lavoro precedente. Notare che lo stato viene ripristinato, in modo simile all'esempio seguente.Nota
Se si passa a un flusso di lavoro che è stato avviato prima dell'abilitazione del rilevamento non viene visualizzato alcuno stato. Tuttavia se si creano tentativi aggiuntivi, lo stato viene salvato in quanto il rilevamento viene così abilitato.
Please enter a number between 1 and 10 Your guess is too high. Please enter a number between 1 and 10
Nota
Queste informazioni sono utili per la scelta dell'intervallo del numero casuale, ma non contiene alcuna informazione sui tentativi effettuati in precedenza. Queste informazioni si trovano nel passaggio successivo, Procedura: Ospitare più versioni di un flusso di lavoro side-by-side.
Annotare l'ID istanza del flusso di lavoro e giocare fino al completamento.
Aprire Esplora risorse e passare alla cartellaNumberGuessWorkflowHost\bin\debug (o bin\release a seconda delle impostazioni del progetto). Si noti che oltre ai file eseguibili di progetto, sono presenti file con nomi file GUID. Identificare quello corrispondente all'ID istanza del flusso di lavoro dal flusso di lavoro completato nel passaggio precedente e aprirlo in Blocco Note. Le informazioni sul rilevamento contengono dati simili al seguente esempio.
Please enter a number between 1 and 10 Your guess is too high. Please enter a number between 1 and 10 Your guess is too high. Please enter a number between 1 and 10
Oltre all'assenza dei tentativi dell'utente, questi dati di rilevamento non contengono informazioni sul tentativo finale del flusso di lavoro. Ciò accade perché le informazioni di rilevamento sono costituite solo dall'output di
WriteLine
restituito dal flusso di lavoro e il messaggio finale visualizzato viene in tal modo creato dal gestoreCompleted
dopo il completamento del flusso di lavoro. Nel passaggio successivo dell'esercitazione, Procedura: Ospitare più versioni di un flusso di lavoro side-by-side, le attivitàWriteLine
esistenti vengono modificate per visualizzare i tentativi dell'utente e viene aggiunta un'altra attivitàWriteLine
che visualizza i risultati finali. Dopo aver integrato queste modifiche, in Procedura: Ospitare più versioni di un flusso di lavoro side-by-side viene illustrato come ospitare più versioni di un flusso di lavoro contemporaneamente.