Instrukcje: Równoczesne hostowanie wielu wersji przepływu pracy
WorkflowIdentity
Zapewnia deweloperom aplikacji przepływu pracy możliwość skojarzenia nazwy i wersji z definicją przepływu pracy oraz skojarzenia tych informacji z utrwalonego wystąpienia przepływu pracy. Te informacje o tożsamości mogą być używane przez deweloperów aplikacji przepływu pracy w celu umożliwienia scenariuszy, takich jak równoległe wykonywanie wielu wersji definicji przepływu pracy, i zapewnia podstawę dla innych funkcji, takich jak aktualizacja dynamiczna. W tym kroku w samouczku pokazano, jak hostować WorkflowIdentity
wiele wersji przepływu pracy w tym samym czasie.
W tym temacie
W tym kroku samouczka WriteLine
działania w przepływie pracy są modyfikowane w celu dostarczenia dodatkowych informacji, a nowe WriteLine
działanie zostanie dodane. Kopia oryginalnego zestawu przepływu pracy jest przechowywana, a aplikacja hosta jest aktualizowana tak, aby mogła uruchamiać zarówno oryginalne, jak i zaktualizowane przepływy pracy w tym samym czasie.
Uwaga
Przed wykonaniem kroków opisanych w tym temacie uruchom aplikację, uruchom kilka przepływów pracy każdego typu i co najmniej jedno zgadywanie dla każdego z nich. Te utrwalone przepływy pracy są używane w tym kroku i w poniższym kroku: Aktualizowanie definicji uruchomionego wystąpienia przepływu pracy.
Aby utworzyć kopię projektu NumberGuessWorkflowActivities
Otwórz rozwiązanie WF45GettingStartedTutorial w programie Visual Studio 2012, jeśli nie jest otwarte.
Naciśnij kombinację klawiszy CTRL+SHIFT+B w celu skompilowania rozwiązania.
Zamknij rozwiązanie WF45GettingStartedTutorial.
Otwórz Eksploratora Windows i przejdź do folderu, w którym znajduje się plik rozwiązania samouczka i foldery projektu.
Utwórz nowy folder o nazwie PreviousVersions w tym samym folderze co NumberGuessWorkflowHost i NumberGuessWorkflowActivities. Ten folder służy do przechowywania zestawów zawierających różne wersje przepływów pracy używanych w kolejnych krokach samouczka.
Przejdź do folderu NumberGuessWorkflowActivities\bin\debug (lub bin\release w zależności od ustawień projektu). Skopiuj NumberGuessWorkflowActivities.dll i wklej go do folderu PreviousVersions .
Zmień nazwę NumberGuessWorkflowActivities.dll w folderze PreviousVersions na NumberGuessWorkflowActivities_v1.dll.
Uwaga
Kroki przedstawione w tym temacie przedstawiają jeden ze sposobów zarządzania zestawami używanymi do przechowywania wielu wersji przepływów pracy. Można również użyć innych metod, takich jak silne nazewnictwo zestawów i zarejestrowanie ich w globalnej pamięci podręcznej zestawów.
Utwórz nowy folder o nazwie NumberGuessWorkflowActivities_du w tym samym folderze co NumberGuessWorkflowHost, NumberGuessWorkflowActivities i nowo dodany folder PreviousVersions, a następnie skopiuj wszystkie pliki i podfoldery z folderu NumberGuessWorkflowActivities do nowego folderu NumberGuessWorkflowActivities_du. Ta kopia zapasowa projektu dla początkowej wersji działań jest używana w temacie How to: Update the Definition of a Running Workflow Instance (Jak zaktualizować definicję uruchomionego wystąpienia przepływu pracy).
Otwórz ponownie rozwiązanie WF45GettingStartedTutorial w programie Visual Studio 2012.
Aby zaktualizować przepływy pracy
W tej sekcji definicje przepływu pracy są aktualizowane. Dwa WriteLine
działania, które dają opinię na temat odgadnięcia użytkownika, są aktualizowane, a nowe WriteLine
działanie jest dodawane, które udostępnia dodatkowe informacje o grze, gdy liczba zostanie odgadnięta.
Aby zaktualizować przepływ pracy StateMachine
W Eksplorator rozwiązań w projekcie NumberGuessWorkflowActivities kliknij dwukrotnie element StateMachineNumberGuessWorkflow.xaml.
Kliknij dwukrotnie przejście Odgadnij niepoprawne na maszynie stanu.
Text
Zaktualizuj element z lewej stronyWriteLine
wIf
działaniu.Guess & " is too low."
Guess + " is too low."
Text
Zaktualizuj element najbardziej odpowiedniegoWriteLine
działaniaIf
.Guess & " is too high."
Guess + " is too high."
Wróć do ogólnego widoku maszyny stanu w projektancie przepływu pracy, klikając pozycję StateMachine w widoku do stron nadrzędnych w górnej części projektanta przepływu pracy.
Kliknij dwukrotnie przejście Guess Correct na maszynie stanu.
Przeciągnij działanie WriteLine z sekcji Typy pierwotne przybornika i upuść je na akcji Upuść tutaj etykietę przejścia.
Wpisz następujące wyrażenie w
Text
polu właściwości.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Aby zaktualizować przepływ pracy schematu blokowego
W Eksplorator rozwiązań w projekcie NumberGuessWorkflowActivities kliknij dwukrotnie pozycję FlowchartNumberGuessWorkflow.xaml.
Text
Zaktualizuj działanie najbardziejWriteLine
po lewej stronie.Guess & " is too low."
Guess + " is too low."
Text
Zaktualizuj działanie najbardziej odpowiednieWriteLine
.Guess & " is too high."
Guess + " is too high."
Przeciągnij działanie WriteLine z sekcji Typy pierwotne przybornika i upuść je w punkcie
True
upuszczania akcji najbardziej u góryFlowDecision
. DziałanieWriteLine
jest dodawane do schematu blokowego i połączone zTrue
akcjąFlowDecision
.Wpisz następujące wyrażenie w
Text
polu właściwości.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Aby zaktualizować sekwencyjny przepływ pracy
W Eksplorator rozwiązań w projekcie NumberGuessWorkflowActivities kliknij dwukrotnie pozycję SequentialNumberGuessWorkflow.xaml.
Text
Zaktualizuj element z lewej stronyWriteLine
wIf
działaniu.Guess & " is too low."
Guess + " is too low."
Text
Zaktualizuj działanie najbardziej odpowiednieWriteLine
wIf
działaniu.Guess & " is too high."
Guess + " is too high."
Przeciągnij działanie WriteLine z sekcji Typy pierwotne przybornika i upuść je po działaniu DoWhile, aby funkcja WriteLine była ostatnim działaniem w działaniu głównym
Sequence
.Wpisz następujące wyrażenie w
Text
polu właściwości.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Aby zaktualizować element WorkflowVersionMap, aby uwzględnić poprzednie wersje przepływu pracy
Kliknij dwukrotnie WorkflowVersionMap.cs (lub WorkflowVersionMap.vb) w projekcie NumberGuessWorkflowHost , aby go otworzyć.
Dodaj następujące
using
instrukcje (lubImports
) na początku pliku z innymiusing
instrukcjami (lubImports
).Imports System.Reflection Imports System.IO
using System.Reflection; using System.IO;
Dodaj trzy nowe tożsamości przepływu pracy tuż poniżej trzech istniejących deklaracji tożsamości przepływu pracy. Te nowe
v1
tożsamości przepływu pracy będą używane do zapewnienia poprawnej definicji przepływu pracy do przepływów pracy uruchomionych przed wprowadzeniem aktualizacji.'Current version identities. Public StateMachineNumberGuessIdentity As WorkflowIdentity Public FlowchartNumberGuessIdentity As WorkflowIdentity Public SequentialNumberGuessIdentity As WorkflowIdentity 'v1 Identities. Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity
// Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; // v1 identities. static public WorkflowIdentity StateMachineNumberGuessIdentity_v1; static public WorkflowIdentity FlowchartNumberGuessIdentity_v1; static public WorkflowIdentity SequentialNumberGuessIdentity_v1;
W konstruktorze
WorkflowVersionMap
zaktualizujVersion
właściwość trzech bieżących tożsamości przepływu pracy na2.0.0.0
.'Add the current workflow version identities. StateMachineNumberGuessIdentity = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } FlowchartNumberGuessIdentity = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } SequentialNumberGuessIdentity = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow()) map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow()) map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow())
// Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow());
Kod, który dodaje bieżące wersje przepływów pracy do słownika, używa bieżących wersji, do których odwołuje się projekt, więc kod, który inicjuje definicje przepływu pracy, nie musi być aktualizowany.
Dodaj następujący kod w konstruktorze tuż po kodzie, który dodaje bieżące wersje do słownika.
'Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) }
// Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) };
Te tożsamości przepływu pracy są skojarzone z początkowymi wersjami odpowiednich definicji przepływu pracy.
Następnie załaduj zestaw zawierający początkową wersję definicji przepływu pracy i utwórz i dodaj odpowiednie definicje przepływu pracy do słownika.
'Add the previous version workflow identities to the dictionary along with 'the corresponding workflow definitions loaded from the v1 assembly. 'Assembly.LoadFile requires an absolute path so convert this relative path 'to an absolute path. Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll" v1AssemblyPath = Path.GetFullPath(v1AssemblyPath) Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath) map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow")) map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow")) map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow"))
// Add the previous version workflow identities to the dictionary along with // the corresponding workflow definitions loaded from the v1 assembly. // Assembly.LoadFile requires an absolute path so convert this relative path // to an absolute path. string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"; v1AssemblyPath = Path.GetFullPath(v1AssemblyPath); Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath); map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity); map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity); map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
Poniższy przykład to kompletna lista zaktualizowanej
WorkflowVersionMap
klasy.Public Module WorkflowVersionMap Dim map As Dictionary(Of WorkflowIdentity, Activity) 'Current version identities. Public StateMachineNumberGuessIdentity As WorkflowIdentity Public FlowchartNumberGuessIdentity As WorkflowIdentity Public SequentialNumberGuessIdentity As WorkflowIdentity 'v1 Identities. Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity Sub New() map = New Dictionary(Of WorkflowIdentity, Activity) 'Add the current workflow version identities. StateMachineNumberGuessIdentity = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } FlowchartNumberGuessIdentity = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } SequentialNumberGuessIdentity = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow()) map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow()) map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow()) 'Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } 'Add the previous version workflow identities to the dictionary along with 'the corresponding workflow definitions loaded from the v1 assembly. 'Assembly.LoadFile requires an absolute path so convert this relative path 'to an absolute path. Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll" v1AssemblyPath = Path.GetFullPath(v1AssemblyPath) Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath) map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow")) map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow")) map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow")) End Sub Public Function GetWorkflowDefinition(identity As WorkflowIdentity) As Activity Return map(identity) End Function Public Function GetIdentityDescription(identity As WorkflowIdentity) As String Return identity.ToString() End Function End Module
public static class WorkflowVersionMap { static Dictionary<WorkflowIdentity, Activity> map; // Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; // v1 identities. static public WorkflowIdentity StateMachineNumberGuessIdentity_v1; static public WorkflowIdentity FlowchartNumberGuessIdentity_v1; static public WorkflowIdentity SequentialNumberGuessIdentity_v1; static WorkflowVersionMap() { map = new Dictionary<WorkflowIdentity, Activity>(); // Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow()); // Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; // Add the previous version workflow identities to the dictionary along with // the corresponding workflow definitions loaded from the v1 assembly. // Assembly.LoadFile requires an absolute path so convert this relative path // to an absolute path. string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"; v1AssemblyPath = Path.GetFullPath(v1AssemblyPath); Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath); map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity); map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity); map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity); } public static Activity GetWorkflowDefinition(WorkflowIdentity identity) { return map[identity]; } public static string GetIdentityDescription(WorkflowIdentity identity) { return identity.ToString(); } }
Aby skompilować i uruchomić aplikację
Naciśnij klawisze CTRL+SHIFT+B, aby skompilować aplikację, a następnie naciśnij klawisze CTRL+F5, aby rozpocząć.
Rozpocznij nowy przepływ pracy, klikając pozycję Nowa gra. Wersja przepływu pracy jest wyświetlana w oknie stanu i odzwierciedla zaktualizowaną wersję ze skojarzonej wersji
WorkflowIdentity
. ZanotujInstanceId
plik śledzenia przepływu pracy po jego zakończeniu, a następnie wprowadź odgadnięcia do momentu ukończenia gry. Zwróć uwagę, jak zgadywanie użytkownika jest wyświetlane w informacjach wyświetlanych w oknie stanu na podstawie aktualizacjiWriteLine
działań.Please enter a number between 1 and 10 5 is too high. Please enter a number between 1 and 10 3 is too high. Please enter a number between 1 and 10 1 is too low. Please enter a number between 1 and 10 Congratulations, you guessed the number in 4 turns.
Uwaga
Zostanie wyświetlony zaktualizowany tekst z
WriteLine
działań, ale dane wyjściowe końcowegoWriteLine
działania dodanego w tym temacie nie są. Dzieje się tak, ponieważ okno stanu jest aktualizowane przezPersistableIdle
program obsługi. Ponieważ przepływ pracy kończy się i nie przechodzi w stan bezczynności po ostatnim działaniu,PersistableIdle
program obsługi nie jest wywoływany. Jednak podobny komunikat jest wyświetlany w oknie stanu przezCompleted
program obsługi. W razie potrzeby można dodać kod doCompleted
programu obsługi, aby wyodrębnić tekst z obiektuStringWriter
i wyświetlić go w oknie stanu.Otwórz Eksploratora Windows i przejdź do folderu NumberGuessWorkflowHost\bin\debug (lub bin\release w zależności od ustawień projektu) i otwórz plik śledzenia przy użyciu Notatnik, który odpowiada ukończonym przepływowi pracy. Jeśli nie zanotujesz
InstanceId
pliku , możesz zidentyfikować prawidłowy plik śledzenia przy użyciu informacji o dacie zmodyfikowanej w Eksploratorze Windows.Please enter a number between 1 and 10 5 is too high. Please enter a number between 1 and 10 3 is too high. Please enter a number between 1 and 10 1 is too low. Please enter a number between 1 and 10 2 is correct. You guessed it in 4 turns.
Zaktualizowane
WriteLine
dane wyjściowe znajdują się w pliku śledzenia, w tym dane wyjścioweWriteLine
dodane w tym temacie.Wróć do aplikacji do odgadnięcia liczb i wybierz jeden z przepływów pracy, które zostały uruchomione przed wprowadzeniem aktualizacji. Możesz zidentyfikować wersję aktualnie wybranego przepływu pracy, przeglądając informacje o wersji wyświetlane poniżej okna stanu. Wprowadź kilka odgadnięć i zwróć uwagę, że aktualizacje stanu są zgodne
WriteLine
z danymi wyjściowymi działania z poprzedniej wersji i nie zawierają odgadnięcia użytkownika. Wynika to z faktu, że te przepływy pracy używają poprzedniej definicji przepływu pracy, która nie maWriteLine
aktualizacji.W następnym kroku , Instrukcje: aktualizowanie definicji uruchomionego wystąpienia przepływu pracy, uruchomione
v1
wystąpienia przepływu pracy są aktualizowane, aby zawierały nowe funkcje jakov2
wystąpienia.