Instrukcje: Tworzenie niestandardowego uczestnika śledzenia
Śledzenie przepływu pracy zapewnia wgląd w stan wykonywania przepływu pracy. Środowisko uruchomieniowe przepływu pracy emituje rekordy śledzenia opisujące zdarzenia cyklu życia przepływu pracy, zdarzenia cyklu aktywności, wznawianie zakładek i błędy. Te rekordy śledzenia są używane przez śledzenie uczestników. Program Windows Workflow Foundation (WF) zawiera standardowego uczestnika śledzenia, który zapisuje rekordy śledzenia jako śledzenie zdarzeń systemu Windows (ETW). Które nie spełnia wymagań, można także napisać uczestnikiem niestandardowe śledzenia. W tym kroku samouczka opisano sposób tworzenia niestandardowego uczestnika śledzenia i profilu śledzenia, który przechwytuje dane wyjściowe WriteLine
działań, aby można było je wyświetlić użytkownikowi.
Aby utworzyć niestandardowego uczestnika śledzenia
Kliknij prawym przyciskiem myszy pozycję NumberGuessWorkflowHost w Eksplorator rozwiązań i wybierz polecenie Dodaj, Klasa. Wpisz
StatusTrackingParticipant
w polu Nazwa , a następnie kliknij przycisk Dodaj.Dodaj następujące
using
instrukcje (lubImports
) w górnej części pliku z innymiusing
instrukcjami (lubImports
).Imports System.Activities.Tracking Imports System.IO
using System.Activities.Tracking; using System.IO;
Zmodyfikuj klasę
StatusTrackingParticipant
tak, aby dziedziczyła z klasyTrackingParticipant
.Public Class StatusTrackingParticipant Inherits TrackingParticipant End Class
class StatusTrackingParticipant : TrackingParticipant { }
Dodaj następującą
Track
metodę zastąpienia. Istnieje kilka różnych typów rekordów śledzenia. Interesuje nas dane wyjścioweWriteLine
działań, które znajdują się w rekordach śledzenia aktywności.TrackingRecord
Jeśli element jest elementemWriteLine
ActivityTrackingRecord
działania, elementText
jestWriteLine
dołączany do pliku o nazwie poInstanceId
przepływie pracy. W tym samouczku plik jest zapisywany w bieżącym folderze aplikacji hosta.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(); } } } }
Jeśli nie określono profilu śledzenia, zostanie użyty domyślny profil śledzenia. Gdy jest używany domyślny profil śledzenia, rekordy śledzenia są emitowane dla wszystkich
ActivityStates
. Ponieważ musimy przechwycić tekst tylko raz w cyklu życiaWriteLine
działania, wyodrębniamy tylko tekst zeActivityStates.Executing
stanu. W obszarze Aby utworzyć profil śledzenia i zarejestrować uczestnika śledzenia, tworzony jest profil śledzenia określający, że emitowane są tylkoWriteLine
ActivityStates.Executing
rekordy śledzenia.
Aby utworzyć profil śledzenia i zarejestrować uczestnika śledzenia
Kliknij prawym przyciskiem myszy pozycję WorkflowHostForm w Eksplorator rozwiązań i wybierz polecenie Wyświetl kod.
Dodaj następującą
using
instrukcję (lubImports
) w górnej części pliku z innymiusing
instrukcjami (lubImports
).Imports System.Activities.Tracking
using System.Activities.Tracking;
Dodaj następujący kod tuż
ConfigureWorkflowApplication
po kodzie, który dodajeStringWriter
element do rozszerzeń przepływu pracy i przed procedurami obsługi cyklu życia przepływu pracy.'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);
Ten profil śledzenia określa, że tylko rekordy stanu działania dla
WriteLine
działań wExecuting
stanie są emitowane do niestandardowego uczestnika śledzenia.Po dodaniu kodu początek będzie wyglądać podobnie do poniższego przykładu
ConfigureWorkflowApplication
.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...
Aby wyświetlić informacje o śledzeniu
Kliknij prawym przyciskiem myszy pozycję WorkflowHostForm w Eksplorator rozwiązań i wybierz polecenie Wyświetl kod.
W procedurze
InstanceId_SelectedIndexChanged
obsługi dodaj następujący kod natychmiast po kodzie, który czyści okno stanu.'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); }
Po wybraniu nowego przepływu pracy na liście przepływów pracy rekordy śledzenia dla tego przepływu pracy są ładowane i wyświetlane w oknie stanu. Poniższy przykład to ukończona
InstanceId_SelectedIndexChanged
procedura obsługi.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(); } }
Aby skompilować i uruchomić aplikację
Naciśnij Ctrl+Shift+B, aby skompilować aplikację.
Naciśnij Ctrl+F5, aby uruchomić aplikację.
Wybierz zakres dla gry zgadywania i typu przepływu pracy do uruchomienia, a następnie kliknij pozycję Nowa gra. Wprowadź wartość zgadnij w polu Odgadnij i kliknij przycisk Przejdź, aby przesłać swoje odgadnięcie. Należy pamiętać, że stan przepływu pracy jest wyświetlany w oknie stanu. Te dane wyjściowe są przechwytywane z
WriteLine
działań. Przejdź do innego przepływu pracy, wybierając jeden z pola kombi Identyfikator wystąpienia przepływu pracy i zwróć uwagę, że stan bieżącego przepływu pracy został usunięty. Wróć do poprzedniego przepływu pracy i zwróć uwagę, że stan jest przywracany, podobnie jak w poniższym przykładzie.Uwaga
Jeśli przełączysz się do przepływu pracy, który został uruchomiony przed włączeniem śledzenia, nie zostanie wyświetlony stan. Jeśli jednak wprowadzisz dodatkowe zgadnięcia, ich stan zostanie zapisany, ponieważ śledzenie jest teraz włączone.
Please enter a number between 1 and 10 Your guess is too high. Please enter a number between 1 and 10
Uwaga
Te informacje są przydatne do określania zakresu liczby losowej, ale nie zawierają żadnych informacji o tym, co zostały wcześniej wykonane. Te informacje są dostępne w następnym kroku: Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie.
Zanotuj identyfikator wystąpienia przepływu pracy i przetwórz grę do jego ukończenia.
Otwórz Eksploratora Windows i przejdź do folderu NumberGuessWorkflowHost\bin\debug (lub bin\release w zależności od ustawień projektu). Należy pamiętać, że oprócz plików wykonywalnych projektu istnieją pliki z nazwami plików guid. Zidentyfikuj identyfikator wystąpienia przepływu pracy z ukończonego przepływu pracy w poprzednim kroku i otwórz go w Notatniku. Informacje dotyczące śledzenia zawierają informacje podobne do poniższych.
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
Oprócz braku odgadnięcia użytkownika te dane śledzenia nie zawierają informacji na temat końcowego zgadywania przepływu pracy. Wynika to z faktu, że informacje śledzenia składają się tylko
WriteLine
z danych wyjściowych z przepływu pracy, a ostatni wyświetlany komunikat jest wykonywany tak zCompleted
programu obsługi po zakończeniu przepływu pracy. W następnym kroku samouczka Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie, istniejąceWriteLine
działania są modyfikowane w celu wyświetlania odgadnięć użytkownika, a dodatkoweWriteLine
działanie jest dodawane, które wyświetla końcowe wyniki. Po zintegrowaniu tych zmian instrukcje : hostowanie wielu wersji przepływu pracy obok siebie pokazuje, jak hostować wiele wersji przepływu pracy w tym samym czasie.