Udostępnij za pośrednictwem


Instrukcje: aktualizowanie definicji uruchomionego wystąpienia przepływu pracy

Aktualizacja dynamiczna udostępnia mechanizm dla deweloperów aplikacji przepływu pracy w celu zaktualizowania definicji przepływu pracy utrwalonego wystąpienia przepływu pracy. Wymaganą zmianą może być zaimplementowanie poprawki błędów, nowych wymagań lub uwzględnienia nieoczekiwanych zmian. W tym kroku w samouczku pokazano, jak używać aktualizacji dynamicznej do modyfikowania utrwalonego wystąpienia v1 przepływu pracy zgadywania liczb w celu dopasowania do nowych funkcji wprowadzonych w temacie Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie.

Aby utworzyć projekt CreateUpdateMaps

  1. Kliknij prawym przyciskiem myszy pozycję WF45GettingStartedTutorial w Eksplorator rozwiązań i wybierz polecenie Dodaj nowy projekt.

  2. W węźle Zainstalowany wybierz pozycję Visual C#, Windows (lub Visual Basic, Windows).

    Uwaga

    W zależności od tego, który język programowania jest skonfigurowany jako język podstawowy w programie Visual Studio, węzeł Visual C# lub Visual Basic może znajdować się w węźle Inne języki w węźle Zainstalowane .

    Upewnij się, że program .NET Framework 4.5 został wybrany na liście rozwijanej Wersja programu .NET Framework. Wybierz pozycję Aplikacja konsolowa z listy systemu Windows . Wpisz CreateUpdateMaps w polu Nazwa i kliknij przycisk OK.

  3. Kliknij prawym przyciskiem myszy pozycję CreateUpdateMaps w Eksplorator rozwiązań i wybierz polecenie Dodaj odwołanie.

  4. Wybierz pozycję Struktura z węzła Zestawy na liście Dodaj odwołanie . Wpisz Ciąg System.Activities w polu Wyszukaj zestawy , aby filtrować zestawy i ułatwić wybór żądanych odwołań.

  5. Zaznacz pole wyboru obok pozycji System.Activities z listy Wyniki wyszukiwania.

  6. Wpisz serializacji w polu Wyszukaj zestawy i zaznacz pole wyboru obok pozycji System.Runtime.Serialization z listy Wyniki wyszukiwania.

  7. Wpisz Ciąg System.Xaml w polu Wyszukaj zestawy i zaznacz pole wyboru obok pozycji System.Xaml z listy Wyniki wyszukiwania.

  8. Kliknij przycisk OK , aby zamknąć Menedżera odwołań i dodać odwołania.

  9. Dodaj następujące using instrukcje (lub Imports) w górnej części pliku z innymi using instrukcjami (lub Imports).

    Imports System.Activities
    Imports System.Activities.Statements
    Imports System.Xaml
    Imports System.Reflection
    Imports System.IO
    Imports System.Activities.XamlIntegration
    Imports System.Activities.DynamicUpdate
    Imports System.Runtime.Serialization
    Imports Microsoft.VisualBasic.Activities
    
    using System.Activities;
    using System.Activities.Statements;
    using System.IO;
    using System.Xaml;
    using System.Reflection;
    using System.Activities.XamlIntegration;
    using System.Activities.DynamicUpdate;
    using System.Runtime.Serialization;
    using Microsoft.CSharp.Activities;
    
  10. Dodaj następujące dwa składowe ciągu do Program klasy (lub Module1).

    Const mapPath = "..\..\..\PreviousVersions"
    Const definitionPath = "..\..\..\NumberGuessWorkflowActivities_du"
    
    const string mapPath = @"..\..\..\PreviousVersions";
    const string definitionPath = @"..\..\..\NumberGuessWorkflowActivities_du";
    
  11. Dodaj następującą StartUpdate metodę do Program klasy (lub Module1). Ta metoda ładuje określoną definicję przepływu pracy xaml do elementu , a następnie wywołuje metodę ActivityBuilderDynamicUpdate.PrepareForUpdate. PrepareForUpdate Tworzy kopię definicji przepływu pracy wewnątrz ActivityBuilderelementu . Po zmodyfikowaniu definicji przepływu pracy ta kopia jest używana wraz ze zmodyfikowaną definicją przepływu pracy w celu utworzenia mapy aktualizacji.

    Private Function StartUpdate(name As String) As ActivityBuilder
        'Create the XamlXmlReaderSettings.
        Dim readerSettings As XamlReaderSettings = New XamlXmlReaderSettings()
        'In the XAML the "local" namespace refers to artifacts that come from
        'the same project as the XAML. When loading XAML if the currently executing
        'assembly is not the same assembly that was referred to as "local" in the XAML
        'LocalAssembly must be set to the assembly containing the artifacts.
        'Assembly.LoadFile requires an absolute path so convert this relative path
        'to an absolute path.
        readerSettings.LocalAssembly = Assembly.LoadFile(
            Path.GetFullPath(Path.Combine(mapPath, "NumberGuessWorkflowActivities_v1.dll")))
    
        Dim fullPath As String = Path.Combine(definitionPath, name)
        Dim xamlReader As XamlXmlReader = New XamlXmlReader(fullPath, readerSettings)
    
        'Load the workflow definition into an ActivityBuilder.
        Dim wf As ActivityBuilder = XamlServices.Load(
            ActivityXamlServices.CreateBuilderReader(xamlReader))
    
        'PrepareForUpdate makes a copy of the workflow definition in the
        'ActivityBuilder that is used for comparison when the update
        'map is created.
        DynamicUpdateServices.PrepareForUpdate(wf)
    
        Return wf
    End Function
    
    private static ActivityBuilder StartUpdate(string name)
    {
        // Create the XamlXmlReaderSettings.
        XamlXmlReaderSettings readerSettings = new XamlXmlReaderSettings()
        {
            // In the XAML the "local" namespace refers to artifacts that come from
            // the same project as the XAML. When loading XAML if the currently executing
            // assembly is not the same assembly that was referred to as "local" in the XAML
            // LocalAssembly must be set to the assembly containing the artifacts.
            // Assembly.LoadFile requires an absolute path so convert this relative path
            // to an absolute path.
            LocalAssembly = Assembly.LoadFile(
                Path.GetFullPath(Path.Combine(mapPath, "NumberGuessWorkflowActivities_v1.dll")))
        };
    
        string path = Path.Combine(definitionPath, name);
        XamlXmlReader xamlReader = new XamlXmlReader(path, readerSettings);
    
        // Load the workflow definition into an ActivityBuilder.
        ActivityBuilder wf = XamlServices.Load(
            ActivityXamlServices.CreateBuilderReader(xamlReader))
            as ActivityBuilder;
    
        // PrepareForUpdate makes a copy of the workflow definition in the
        // ActivityBuilder that is used for comparison when the update
        // map is created.
        DynamicUpdateServices.PrepareForUpdate(wf);
    
        return wf;
    }
    
  12. Następnie dodaj następujący kod CreateUpdateMethod do Program klasy (lub Module1). Spowoduje to utworzenie dynamicznej mapy aktualizacji przez wywołanie metody DynamicUpdateServices.CreateUpdateMap, a następnie zapisanie mapy aktualizacji przy użyciu określonej nazwy. Ta mapa aktualizacji zawiera informacje wymagane przez środowisko uruchomieniowe przepływu pracy w celu zaktualizowania utrwalonego wystąpienia przepływu pracy, które zostało uruchomione przy użyciu oryginalnej definicji przepływu pracy zawartej w ActivityBuilder pliku , tak aby zakończyło się przy użyciu zaktualizowanej definicji przepływu pracy.

    Private Sub CreateUpdateMaps(wf As ActivityBuilder, name As String)
        'Create the UpdateMap.
        Dim map As DynamicUpdateMap =
            DynamicUpdateServices.CreateUpdateMap(wf)
    
        'Serialize it to a file.
        Dim mapFullPath As String = Path.Combine(mapPath, name)
        Dim sz As DataContractSerializer = New DataContractSerializer(GetType(DynamicUpdateMap))
        Using fs As FileStream = File.Open(mapFullPath, FileMode.Create)
            sz.WriteObject(fs, map)
        End Using
    End Sub
    
    private static void CreateUpdateMaps(ActivityBuilder wf, string name)
    {
        // Create the UpdateMap.
        DynamicUpdateMap map =
            DynamicUpdateServices.CreateUpdateMap(wf);
    
        // Serialize it to a file.
        string path = Path.Combine(mapPath, name);
        DataContractSerializer sz = new DataContractSerializer(typeof(DynamicUpdateMap));
        using (FileStream fs = System.IO.File.Open(path, FileMode.Create))
        {
            sz.WriteObject(fs, map);
        }
    }
    
  13. Dodaj następującą SaveUpdatedDefinition metodę do Program klasy (lub Module1). Ta metoda zapisuje zaktualizowaną definicję przepływu pracy po utworzeniu mapy aktualizacji.

    Private Sub SaveUpdatedDefinition(wf As ActivityBuilder, name As String)
        Dim xamlPath As String = Path.Combine(definitionPath, name)
        Dim sw As StreamWriter = File.CreateText(xamlPath)
        Dim xw As XamlWriter = ActivityXamlServices.CreateBuilderWriter(
            New XamlXmlWriter(sw, New XamlSchemaContext()))
        XamlServices.Save(xw, wf)
        sw.Close()
    End Sub
    
    private static void SaveUpdatedDefinition(ActivityBuilder wf, string name)
    {
        string xamlPath = Path.Combine(definitionPath, name);
        StreamWriter sw = File.CreateText(xamlPath);
        XamlWriter xw = ActivityXamlServices.CreateBuilderWriter(
            new XamlXmlWriter(sw, new XamlSchemaContext()));
        XamlServices.Save(xw, wf);
        sw.Close();
    }
    

Aby zaktualizować StateMachineNumberGuessWorkflow

  1. Dodaj element CreateStateMachineUpdateMap do Program klasy (lub Module1).

    Private Sub CreateStateMachineUpdateMap()
    
    End Sub
    
    private static void CreateStateMachineUpdateMap()
    {
    }
    
  2. Wywołaj metodę StartUpdate , a następnie uzyskaj odwołanie do działania głównego StateMachine przepływu pracy.

    Dim wf As ActivityBuilder = StartUpdate("StateMachineNumberGuessWorkflow.xaml")
    
    'Get a reference to the root StateMachine activity.
    Dim sm As StateMachine = wf.Implementation
    
    ActivityBuilder wf = StartUpdate("StateMachineNumberGuessWorkflow.xaml");
    
    // Get a reference to the root StateMachine activity.
    StateMachine sm = wf.Implementation as StateMachine;
    
  3. Następnie zaktualizuj wyrażenia dwóch WriteLine działań, które wyświetlają, czy odgadnięcie użytkownika jest zbyt wysokie, czy zbyt niskie, tak aby były zgodne z aktualizacjami w temacie Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie.

    'Update the Text of the two WriteLine activities that write the
    'results of the user's guess. They are contained in the workflow as the
    'Then and Else action of the If activity in sm.States[1].Transitions[1].Action.
    Dim guessLow As Statements.If = sm.States(1).Transitions(1).Action
    
    'Update the "too low" message.
    Dim tooLow As WriteLine = guessLow.Then
    tooLow.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too low.""")
    
    'Update the "too high" message.
    Dim tooHigh As WriteLine = guessLow.Else
    tooHigh.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too high.""")
    
    // Update the Text of the two WriteLine activities that write the
    // results of the user's guess. They are contained in the workflow as the
    // Then and Else action of the If activity in sm.States[1].Transitions[1].Action.
    If guessLow = sm.States[1].Transitions[1].Action as If;
    
    // Update the "too low" message.
    WriteLine tooLow = guessLow.Then as WriteLine;
    tooLow.Text = new CSharpValue<string>("Guess.ToString() + \" is too low.\"");
    
    // Update the "too high" message.
    WriteLine tooHigh = guessLow.Else as WriteLine;
    tooHigh.Text = new CSharpValue<string>("Guess.ToString() + \" is too high.\"");
    
  4. Następnie dodaj nowe WriteLine działanie, które wyświetla komunikat zamykający.

    'Create the new WriteLine that displays the closing message.
    Dim wl As New WriteLine() With
    {
        .Text = New VisualBasicValue(Of String) _
            ("Guess.ToString() + "" is correct. You guessed it in "" & Turns.ToString() & "" turns.""")
    }
    
    'Add it as the Action for the Guess Correct transition. The Guess Correct
    'transition is the first transition of States[1]. The transitions are listed
    'at the bottom of the State activity designer.
    sm.States(1).Transitions(0).Action = wl
    
    // Create the new WriteLine that displays the closing message.
    WriteLine wl = new WriteLine
    {
        Text = new CSharpValue<string>("Guess.ToString() + \" is correct. You guessed it in \" + Turns.ToString() + \" turns.\"")
    };
    
    // Add it as the Action for the Guess Correct transition. The Guess Correct
    // transition is the first transition of States[1]. The transitions are listed
    // at the bottom of the State activity designer.
    sm.States[1].Transitions[0].Action = wl;
    
  5. Po zaktualizowaniu przepływu pracy wywołaj metodę CreateUpdateMaps i SaveUpdatedDefinition. CreateUpdateMapsprogram tworzy i zapisuje DynamicUpdateMapSaveUpdatedDefinition zaktualizowaną definicję przepływu pracy.

    'Create the update map.
    CreateUpdateMaps(wf, "StateMachineNumberGuessWorkflow.map")
    
    'Save the updated workflow definition.
    SaveUpdatedDefinition(wf, "StateMachineNumberGuessWorkflow_du.xaml")
    
    // Create the update map.
    CreateUpdateMaps(wf, "StateMachineNumberGuessWorkflow.map");
    
    // Save the updated workflow definition.
    SaveUpdatedDefinition(wf, "StateMachineNumberGuessWorkflow_du.xaml");
    

    Poniższy przykład to ukończona CreateStateMachineUpdateMap metoda.

    Private Sub CreateStateMachineUpdateMap()
        Dim wf As ActivityBuilder = StartUpdate("StateMachineNumberGuessWorkflow.xaml")
    
        'Get a reference to the root StateMachine activity.
        Dim sm As StateMachine = wf.Implementation
    
        'Update the Text of the two WriteLine activities that write the
        'results of the user's guess. They are contained in the workflow as the
        'Then and Else action of the If activity in sm.States[1].Transitions[1].Action.
        Dim guessLow As Statements.If = sm.States(1).Transitions(1).Action
    
        'Update the "too low" message.
        Dim tooLow As WriteLine = guessLow.Then
        tooLow.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too low.""")
    
        'Update the "too high" message.
        Dim tooHigh As WriteLine = guessLow.Else
        tooHigh.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too high.""")
    
        'Create the new WriteLine that displays the closing message.
        Dim wl As New WriteLine() With
        {
            .Text = New VisualBasicValue(Of String) _
                ("Guess.ToString() + "" is correct. You guessed it in "" & Turns.ToString() & "" turns.""")
        }
    
        'Add it as the Action for the Guess Correct transition. The Guess Correct
        'transition is the first transition of States[1]. The transitions are listed
        'at the bottom of the State activity designer.
        sm.States(1).Transitions(0).Action = wl
    
        'Create the update map.
        CreateUpdateMaps(wf, "StateMachineNumberGuessWorkflow.map")
    
        'Save the updated workflow definition.
        SaveUpdatedDefinition(wf, "StateMachineNumberGuessWorkflow_du.xaml")
    End Sub
    
    private static void CreateStateMachineUpdateMap()
    {
        ActivityBuilder wf = StartUpdate("StateMachineNumberGuessWorkflow.xaml");
    
        // Get a reference to the root StateMachine activity.
        StateMachine sm = wf.Implementation as StateMachine;
    
        // Update the Text of the two WriteLine activities that write the
        // results of the user's guess. They are contained in the workflow as the
        // Then and Else action of the If activity in sm.States[1].Transitions[1].Action.
        If guessLow = sm.States[1].Transitions[1].Action as If;
    
        // Update the "too low" message.
        WriteLine tooLow = guessLow.Then as WriteLine;
        tooLow.Text = new CSharpValue<string>("Guess.ToString() + \" is too low.\"");
    
        // Update the "too high" message.
        WriteLine tooHigh = guessLow.Else as WriteLine;
        tooHigh.Text = new CSharpValue<string>("Guess.ToString() + \" is too high.\"");
    
        // Create the new WriteLine that displays the closing message.
        WriteLine wl = new WriteLine
        {
            Text = new CSharpValue<string>("Guess.ToString() + \" is correct. You guessed it in \" + Turns.ToString() + \" turns.\"")
        };
    
        // Add it as the Action for the Guess Correct transition. The Guess Correct
        // transition is the first transition of States[1]. The transitions are listed
        // at the bottom of the State activity designer.
        sm.States[1].Transitions[0].Action = wl;
    
        // Create the update map.
        CreateUpdateMaps(wf, "StateMachineNumberGuessWorkflow.map");
    
        // Save the updated workflow definition.
        SaveUpdatedDefinition(wf, "StateMachineNumberGuessWorkflow_du.xaml");
    }
    

Aby zaktualizować schemat blokowyNumberGuessWorkflow

  1. Dodaj następujący kod CreateFlowchartUpdateMethod do Program klasy (lub Module1). Ta metoda jest podobna do CreateStateMachineUpdateMapmetody . Rozpoczyna się od wywołania metody StartUpdate, aktualizuje definicję przepływu pracy schematu blokowego i kończy się, zapisując mapę aktualizacji i zaktualizowaną definicję przepływu pracy.

    Private Sub CreateFlowchartUpdateMap()
        Dim wf As ActivityBuilder = StartUpdate("FlowchartNumberGuessWorkflow.xaml")
    
        'Get a reference to the root Flowchart activity.
        Dim fc As Flowchart = wf.Implementation
    
        'Update the Text of the two WriteLine activities that write the
        'results of the user's guess. They are contained in the workflow as the
        'True and False action of the "Guess < Target" FlowDecision, which is
        'Nodes[4].
        Dim guessLow As FlowDecision = fc.Nodes(4)
    
        'Update the "too low" message.
        Dim trueStep As FlowStep = guessLow.True
        Dim tooLow As WriteLine = trueStep.Action
        tooLow.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too low.""")
    
        'Update the "too high" message.
        Dim falseStep As FlowStep = guessLow.False
        Dim tooHigh As WriteLine = falseStep.Action
        tooHigh.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too high.""")
    
        'Create the new WriteLine that displays the closing message.
        Dim wl As New WriteLine() With
        {
            .Text = New VisualBasicValue(Of String) _
                ("Guess.ToString() + "" is correct. You guessed it in "" & Turns.ToString() & "" turns.""")
        }
    
        'Create a FlowStep to hold the WriteLine.
        Dim closingStep As New FlowStep() With
        {
            .Action = wl
        }
    
        'Add this new FlowStep to the True action of the
        '"Guess = Guess" FlowDecision
        Dim guessCorrect As FlowDecision = fc.Nodes(3)
        guessCorrect.True = closingStep
    
        'Add the new FlowStep to the Nodes collection.
        'If closingStep was replacing an existing node then
        'we would need to remove that Step from the collection.
        'In this example there was no existing True step to remove.
        fc.Nodes.Add(closingStep)
    
        'Create the update map.
        CreateUpdateMaps(wf, "FlowchartNumberGuessWorkflow.map")
    
        'Save the updated workflow definition.
        SaveUpdatedDefinition(wf, "FlowchartNumberGuessWorkflow_du.xaml")
    End Sub
    
    private static void CreateFlowchartUpdateMap()
    {
        ActivityBuilder wf = StartUpdate("FlowchartNumberGuessWorkflow.xaml");
    
        // Get a reference to the root Flowchart activity.
        Flowchart fc = wf.Implementation as Flowchart;
    
        // Update the Text of the two WriteLine activities that write the
        // results of the user's guess. They are contained in the workflow as the
        // True and False action of the "Guess < Target" FlowDecision, which is
        // Nodes[4].
        FlowDecision guessLow = fc.Nodes[4] as FlowDecision;
    
        // Update the "too low" message.
        FlowStep trueStep = guessLow.True as FlowStep;
        WriteLine tooLow = trueStep.Action as WriteLine;
        tooLow.Text = new CSharpValue<string>("Guess.ToString() + \" is too low.\"");
    
        // Update the "too high" message.
        FlowStep falseStep = guessLow.False as FlowStep;
        WriteLine tooHigh = falseStep.Action as WriteLine;
        tooHigh.Text = new CSharpValue<string>("Guess.ToString() + \" is too high.\"");
    
        // Add the new WriteLine that displays the closing message.
        WriteLine wl = new WriteLine
        {
            Text = new CSharpValue<string>("Guess.ToString() + \" is correct. You guessed it in \" + Turns.ToString() + \" turns.\"")
        };
    
        // Create a FlowStep to hold the WriteLine.
        FlowStep closingStep = new FlowStep
        {
            Action = wl
        };
    
        // Add this new FlowStep to the True action of the
        // "Guess == Guess" FlowDecision
        FlowDecision guessCorrect = fc.Nodes[3] as FlowDecision;
        guessCorrect.True = closingStep;
    
        // Add the new FlowStep to the Nodes collection.
        // If closingStep was replacing an existing node then
        // we would need to remove that Step from the collection.
        // In this example there was no existing True step to remove.
        fc.Nodes.Add(closingStep);
    
        // Create the update map.
        CreateUpdateMaps(wf, "FlowchartNumberGuessWorkflow.map");
    
        //  Save the updated workflow definition.
        SaveUpdatedDefinition(wf, "FlowchartNumberGuessWorkflow_du.xaml");
    }
    

Aby zaktualizować sekwencyjneNumberGuessWorkflow

  1. Dodaj następujący kod CreateSequentialUpdateMethod do Program klasy (lub Module1). Ta metoda jest podobna do pozostałych dwóch metod. Rozpoczyna się od wywołania metody StartUpdate, aktualizuje sekwencyjną definicję przepływu pracy i kończy się, zapisując mapę aktualizacji i zaktualizowaną definicję przepływu pracy.

    Private Sub CreateSequentialUpdateMap()
        Dim wf As ActivityBuilder = StartUpdate("SequentialNumberGuessWorkflow.xaml")
    
        'Get a reference to the root activity in the workflow.
        Dim rootSequence As Sequence = wf.Implementation
    
        'Update the Text of the two WriteLine activities that write the
        'results of the user's guess. They are contained in the workflow as the
        'Then and Else action of the "Guess < Target" If activity.
        'Sequence[1]->DoWhile->Body->Sequence[2]->If->Then->If
        Dim gameLoop As Statements.DoWhile = rootSequence.Activities(1)
        Dim gameBody As Sequence = gameLoop.Body
        Dim guessCorrect As Statements.If = gameBody.Activities(2)
        Dim guessLow As Statements.If = guessCorrect.Then
        Dim tooLow As WriteLine = guessLow.Then
        tooLow.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too low.""")
        Dim tooHigh As WriteLine = guessLow.Else
        tooHigh.Text = New VisualBasicValue(Of String)("Guess.ToString() & "" is too high.""")
    
        'Create the new WriteLine that displays the closing message.
        Dim wl As New WriteLine() With
        {
            .Text = New VisualBasicValue(Of String) _
                ("Guess.ToString() + "" is correct. You guessed it in "" & Turns.ToString() & "" turns.""")
        }
    
        'Insert it as the third activity in the root sequence
        rootSequence.Activities.Insert(2, wl)
    
        'Create the update map.
        CreateUpdateMaps(wf, "SequentialNumberGuessWorkflow.map")
    
        'Save the updated workflow definition.
        SaveUpdatedDefinition(wf, "SequentialNumberGuessWorkflow_du.xaml")
    End Sub
    
    private static void CreateSequentialUpdateMap()
    {
        ActivityBuilder wf = StartUpdate("SequentialNumberGuessWorkflow.xaml");
    
        // Get a reference to the root activity in the workflow.
        Sequence rootSequence = wf.Implementation as Sequence;
    
        // Update the Text of the two WriteLine activities that write the
        // results of the user's guess. They are contained in the workflow as the
        // Then and Else action of the "Guess < Target" If activity.
        // Sequence[1]->DoWhile->Body->Sequence[2]->If->Then->If
        DoWhile gameLoop = rootSequence.Activities[1] as DoWhile;
        Sequence gameBody = gameLoop.Body as Sequence;
        If guessCorrect = gameBody.Activities[2] as If;
        If guessLow = guessCorrect.Then as If;
        WriteLine tooLow = guessLow.Then as WriteLine;
        tooLow.Text = new CSharpValue<string>("Guess.ToString() + \" is too low.\"");
        WriteLine tooHigh = guessLow.Else as WriteLine;
        tooHigh.Text = new CSharpValue<string>("Guess.ToString() + \" is too high.\"");
    
        // Add the new WriteLine that displays the closing message.
        WriteLine wl = new WriteLine
        {
            Text = new CSharpValue<string>("Guess.ToString() + \" is correct. You guessed it in \" + Turns.ToString() + \" turns.\"")
        };
    
        // Insert it as the third activity in the root sequence
        rootSequence.Activities.Insert(2, wl);
    
        // Create the update map.
        CreateUpdateMaps(wf, "SequentialNumberGuessWorkflow.map");
    
        // Save the updated workflow definition.
        SaveUpdatedDefinition(wf, "SequentialNumberGuessWorkflow_du.xaml");
    }
    

Aby skompilować i uruchomić aplikację CreateUpdateMaps

  1. Zaktualizuj metodę Main i dodaj następujące trzy wywołania metody. Te metody są dodawane w poniższych sekcjach. Każda metoda aktualizuje odpowiedni przepływ pracy odgadnięcia liczb i tworzy element DynamicUpdateMap opisujący aktualizacje.

    Sub Main()
        'Create the update maps for the changes needed to the v1 activities
        'so they match the v2 activities.
        CreateSequentialUpdateMap()
        CreateFlowchartUpdateMap()
        CreateStateMachineUpdateMap()
    End Sub
    
    static void Main(string[] args)
    {
        // Create the update maps for the changes needed to the v1 activities
        // so they match the v2 activities.
        CreateSequentialUpdateMap();
        CreateFlowchartUpdateMap();
        CreateStateMachineUpdateMap();
    }
    
  2. Kliknij prawym przyciskiem myszy pozycję CreateUpdateMaps w Eksplorator rozwiązań i wybierz polecenie Ustaw jako projekt startowy.

  3. Naciśnij CTRL+SHIFT+B, aby skompilować rozwiązanie, a następnie naciśnij CTRL+F5, aby uruchomić aplikację CreateUpdateMaps .

    Uwaga

    Aplikacja CreateUpdateMaps nie wyświetla żadnych informacji o stanie podczas działania, ale jeśli spojrzysz na folder NumberGuessWorkflowActivities_du i folder PreviousVersions , zobaczysz zaktualizowane pliki definicji przepływu pracy i mapy aktualizacji.

    Po utworzeniu map aktualizacji i zaktualizowaniu definicji przepływu pracy następnym krokiem jest utworzenie zaktualizowanego zestawu przepływu pracy zawierającego zaktualizowane definicje.

Aby skompilować zaktualizowany zestaw przepływu pracy

  1. Otwórz drugie wystąpienie programu Visual Studio 2012.

  2. Wybierz pozycję Otwórz, Projekt/Rozwiązanie z menu Plik .

  3. Przejdź do folderu NumberGuessWorkflowActivities_du utworzonego w temacie Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie, wybierz kolejno pozycje NumberGuessWorkflowActivities.csproj (lub vbproj), a następnie kliknij przycisk Otwórz.

  4. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję SekwencyjneNumberGuessWorkflow.xaml i wybierz polecenie Wyklucz z projektu. Zrób to samo w przypadku schematu blokowegoNumberGuessWorkflow.xaml i StateMachineNumberGuessWorkflow.xaml. Ten krok usuwa poprzednie wersje definicji przepływu pracy z projektu.

  5. Wybierz pozycję Dodaj istniejący element z menu Projekt .

  6. Przejdź do folderu NumberGuessWorkflowActivities_du utworzonego w temacie Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie.

  7. Wybierz pozycję Pliki XAML (*.xaml;*.xoml) z listy rozwijanej Pliki typu .

  8. Wybierz pozycję SequentialNumberGuessWorkflow_du.xaml, FlowchartNumberGuessWorkflow_du.xaml i StateMachineNumberGuessWorkflow_du.xaml, a następnie kliknij przycisk Dodaj.

    Uwaga

    CTRL +Kliknij, aby wybrać wiele elementów jednocześnie.

    Ten krok dodaje zaktualizowane wersje definicji przepływu pracy do projektu.

  9. Naciśnij kombinację klawiszy CTRL+SHIFT+B. Projekt zostanie skompilowany.

  10. Wybierz pozycję Zamknij rozwiązanie z menu Plik . Plik rozwiązania dla projektu nie jest wymagany, dlatego kliknij przycisk Nie , aby zamknąć program Visual Studio bez zapisywania pliku rozwiązania. Wybierz pozycję Zakończ z menu Plik , aby zamknąć program Visual Studio.

  11. Otwórz Eksploratora Windows i przejdź do folderu NumberGuessWorkflowActivities_du\bin\Debug (lub bin\Release w zależności od ustawień projektu).

  12. Zmień nazwę NumberGuessWorkflowActivities.dll na NumberGuessWorkflowActivities_v15.dll i skopiuj ją do folderu PreviousVersions utworzonego w temacie Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie.

Aby zaktualizować element WorkflowVersionMap przy użyciu nowych wersji

  1. Wróć do początkowego wystąpienia programu Visual Studio 2012.

  2. Kliknij dwukrotnie WorkflowVersionMap.cs (lub WorkflowVersionMap.vb) w projekcie NumberGuessWorkflowHost , aby go otworzyć.

  3. Dodaj trzy nowe tożsamości przepływu pracy tuż poniżej sześciu istniejących deklaracji tożsamości przepływu pracy. W tym samouczku 1.5.0.0 jest używany jako WorkflowIdentity.Version element tożsamości aktualizacji dynamicznej. Te nowe v15 tożsamości przepływu pracy będą używane w celu zapewnienia prawidłowej definicji przepływu pracy dla dynamicznie aktualizowanych wystąpień utrwalonego przepływu pracy.

    '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
    
    'v1.5 (Dynamic Update) identities.
    Public StateMachineNumberGuessIdentity_v15 As WorkflowIdentity
    Public FlowchartNumberGuessIdentity_v15 As WorkflowIdentity
    Public SequentialNumberGuessIdentity_v15 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;
    
    // v1.5 (Dynamic Update) identities.
    static public WorkflowIdentity StateMachineNumberGuessIdentity_v15;
    static public WorkflowIdentity FlowchartNumberGuessIdentity_v15;
    static public WorkflowIdentity SequentialNumberGuessIdentity_v15;
    
  4. Dodaj następujący kod na końcu konstruktora. Ten kod inicjuje tożsamości przepływu pracy aktualizacji dynamicznej, ładuje odpowiednie definicje przepływu pracy i dodaje je do słownika wersji przepływu pracy.

    'Initialize the dynamic update workflow identities.
    StateMachineNumberGuessIdentity_v15 = New WorkflowIdentity With
    {
        .Name = "StateMachineNumberGuessWorkflow",
        .Version = New Version(1, 5, 0, 0)
    }
    
    FlowchartNumberGuessIdentity_v15 = New WorkflowIdentity With
    {
        .Name = "FlowchartNumberGuessWorkflow",
        .Version = New Version(1, 5, 0, 0)
    }
    
    SequentialNumberGuessIdentity_v15 = New WorkflowIdentity With
    {
        .Name = "SequentialNumberGuessWorkflow",
        .Version = New Version(1, 5, 0, 0)
    }
    
    'Add the dynamic update workflow identities to the dictionary along with
    'the corresponding workflow definitions loaded from the v15 assembly.
    'Assembly.LoadFile requires an absolute path so convert this relative path
    'to an absolute path.
    Dim v15AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v15.dll"
    v15AssemblyPath = Path.GetFullPath(v15AssemblyPath)
    Dim v15Assembly As Assembly = Assembly.LoadFile(v15AssemblyPath)
    
    map.Add(StateMachineNumberGuessIdentity_v15,
        v15Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow"))
    
    map.Add(SequentialNumberGuessIdentity_v15,
        v15Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow"))
    
    map.Add(FlowchartNumberGuessIdentity_v15,
        v15Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow"))
    
    // Initialize the dynamic update workflow identities.
    StateMachineNumberGuessIdentity_v15 = new WorkflowIdentity
    {
        Name = "StateMachineNumberGuessWorkflow",
        Version = new Version(1, 5, 0, 0)
    };
    
    FlowchartNumberGuessIdentity_v15 = new WorkflowIdentity
    {
        Name = "FlowchartNumberGuessWorkflow",
        Version = new Version(1, 5, 0, 0)
    };
    
    SequentialNumberGuessIdentity_v15 = new WorkflowIdentity
    {
        Name = "SequentialNumberGuessWorkflow",
        Version = new Version(1, 5, 0, 0)
    };
    
    // Add the dynamic update workflow identities to the dictionary along with
    // the corresponding workflow definitions loaded from the v15 assembly.
    // Assembly.LoadFile requires an absolute path so convert this relative path
    // to an absolute path.
    string v15AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v15.dll";
    v15AssemblyPath = Path.GetFullPath(v15AssemblyPath);
    Assembly v15Assembly = Assembly.LoadFile(v15AssemblyPath);
    
    map.Add(StateMachineNumberGuessIdentity_v15,
        v15Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity);
    
    map.Add(SequentialNumberGuessIdentity_v15,
        v15Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity);
    
    map.Add(FlowchartNumberGuessIdentity_v15,
        v15Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
    

    Poniższy przykład to ukończona WorkflowVersionMap klasa.

    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
    
        'v1.5 (Dynamic Update) identities.
        Public StateMachineNumberGuessIdentity_v15 As WorkflowIdentity
        Public FlowchartNumberGuessIdentity_v15 As WorkflowIdentity
        Public SequentialNumberGuessIdentity_v15 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"))
    
            'Initialize the dynamic update workflow identities.
            StateMachineNumberGuessIdentity_v15 = New WorkflowIdentity With
            {
                .Name = "StateMachineNumberGuessWorkflow",
                .Version = New Version(1, 5, 0, 0)
            }
    
            FlowchartNumberGuessIdentity_v15 = New WorkflowIdentity With
            {
                .Name = "FlowchartNumberGuessWorkflow",
                .Version = New Version(1, 5, 0, 0)
            }
    
            SequentialNumberGuessIdentity_v15 = New WorkflowIdentity With
            {
                .Name = "SequentialNumberGuessWorkflow",
                .Version = New Version(1, 5, 0, 0)
            }
    
            'Add the dynamic update workflow identities to the dictionary along with
            'the corresponding workflow definitions loaded from the v15 assembly.
            'Assembly.LoadFile requires an absolute path so convert this relative path
            'to an absolute path.
            Dim v15AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v15.dll"
            v15AssemblyPath = Path.GetFullPath(v15AssemblyPath)
            Dim v15Assembly As Assembly = Assembly.LoadFile(v15AssemblyPath)
    
            map.Add(StateMachineNumberGuessIdentity_v15,
                v15Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow"))
    
            map.Add(SequentialNumberGuessIdentity_v15,
                v15Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow"))
    
            map.Add(FlowchartNumberGuessIdentity_v15,
                v15Assembly.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;
    
        // v1.5 (Dynamic Update) identities.
        static public WorkflowIdentity StateMachineNumberGuessIdentity_v15;
        static public WorkflowIdentity FlowchartNumberGuessIdentity_v15;
        static public WorkflowIdentity SequentialNumberGuessIdentity_v15;
    
        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);
    
            // Initialize the dynamic update workflow identities.
            StateMachineNumberGuessIdentity_v15 = new WorkflowIdentity
            {
                Name = "StateMachineNumberGuessWorkflow",
                Version = new Version(1, 5, 0, 0)
            };
    
            FlowchartNumberGuessIdentity_v15 = new WorkflowIdentity
            {
                Name = "FlowchartNumberGuessWorkflow",
                Version = new Version(1, 5, 0, 0)
            };
    
            SequentialNumberGuessIdentity_v15 = new WorkflowIdentity
            {
                Name = "SequentialNumberGuessWorkflow",
                Version = new Version(1, 5, 0, 0)
            };
    
            // Add the dynamic update workflow identities to the dictionary along with
            // the corresponding workflow definitions loaded from the v15 assembly.
            // Assembly.LoadFile requires an absolute path so convert this relative path
            // to an absolute path.
            string v15AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v15.dll";
            v15AssemblyPath = Path.GetFullPath(v15AssemblyPath);
            Assembly v15Assembly = Assembly.LoadFile(v15AssemblyPath);
    
            map.Add(StateMachineNumberGuessIdentity_v15,
                v15Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity);
    
            map.Add(SequentialNumberGuessIdentity_v15,
                v15Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity);
    
            map.Add(FlowchartNumberGuessIdentity_v15,
                v15Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
        }
    
        public static Activity GetWorkflowDefinition(WorkflowIdentity identity)
        {
            return map[identity];
        }
    
        public static string GetIdentityDescription(WorkflowIdentity identity)
        {
            return identity.ToString();
        }
    }
    
  5. Naciśnij kombinację klawiszy CTRL+SHIFT+B. Projekt zostanie skompilowany.

Aby zastosować aktualizacje dynamiczne

  1. Kliknij prawym przyciskiem myszy pozycję WF45GettingStartedTutorial w Eksplorator rozwiązań i wybierz polecenie Dodaj nowy projekt.

  2. W węźle Zainstalowany wybierz pozycję Visual C#, Windows (lub Visual Basic, Windows).

    Uwaga

    W zależności od tego, który język programowania jest skonfigurowany jako język podstawowy w programie Visual Studio, węzeł Visual C# lub Visual Basic może znajdować się w węźle Inne języki w węźle Zainstalowane .

    Upewnij się, że program .NET Framework 4.5 został wybrany na liście rozwijanej Wersja programu .NET Framework. Wybierz pozycję Aplikacja konsolowa z listy systemu Windows . Wpisz ApplyDynamicUpdate w polu Nazwa i kliknij przycisk OK.

  3. Kliknij prawym przyciskiem myszy pozycję ApplyDynamicUpdate w Eksplorator rozwiązań i wybierz polecenie Dodaj odwołanie.

  4. Kliknij pozycję Rozwiązanie i zaznacz pole wyboru obok pozycji NumberGuessWorkflowHost. To odwołanie jest potrzebne, ApplyDynamicUpdate aby można było użyć NumberGuessWorkflowHost.WorkflowVersionMap klasy .

  5. Wybierz pozycję Struktura z węzła Zestawy na liście Dodaj odwołanie . Wpisz System.Activities w polu Wyszukaj zestawy . Spowoduje to filtrowanie zestawów i ułatwienie wybierania żądanych odwołań.

  6. Zaznacz pole wyboru obok pozycji System.Activities z listy Wyniki wyszukiwania.

  7. Wpisz serializacji w polu Wyszukaj zestawy i zaznacz pole wyboru obok pozycji System.Runtime.Serialization z listy Wyniki wyszukiwania.

  8. Wpisz DurableInstancing w polu Wyszukaj zestawy i zaznacz pole wyboru obok pozycji System.Activities.DurableInstancing i System.Runtime.DurableInstancing z listy Wyniki wyszukiwania.

  9. Kliknij przycisk OK , aby zamknąć Menedżera odwołań i dodać odwołania.

  10. Kliknij prawym przyciskiem myszy pozycję ApplyDynamicUpdate w Eksplorator rozwiązań i wybierz polecenie Dodaj, klasa. Wpisz DynamicUpdateInfo w polu Nazwa i kliknij przycisk Dodaj.

  11. Dodaj do klasy następujące dwa składowe DynamicUpdateInfo . Poniższy przykład to ukończona DynamicUpdateInfo klasa. Ta klasa zawiera informacje o mapie aktualizacji i nowej tożsamości przepływu pracy używanej podczas aktualizowania wystąpienia przepływu pracy.

    Public Class DynamicUpdateInfo
        Public updateMap As DynamicUpdateMap
        Public newIdentity As WorkflowIdentity
    End Class
    
    class DynamicUpdateInfo
    {
        public DynamicUpdateMap updateMap;
        public WorkflowIdentity newIdentity;
    }
    
  12. Dodaj następujące using instrukcje (lub Imports) w górnej części pliku z innymi using instrukcjami (lub Imports).

    Imports System.Activities
    Imports System.Activities.DynamicUpdate
    
    using System.Activities;
    using System.Activities.DynamicUpdate;
    
  13. Kliknij dwukrotnie Program.cs (lub Module1.vb) w Eksplorator rozwiązań.

  14. Dodaj następujące using instrukcje (lub Imports) w górnej części pliku z innymi using instrukcjami (lub Imports).

    Imports NumberGuessWorkflowHost
    Imports System.Data.SqlClient
    Imports System.Activities.DynamicUpdate
    Imports System.IO
    Imports System.Runtime.Serialization
    Imports System.Activities
    Imports System.Activities.DurableInstancing
    
    using NumberGuessWorkflowHost;
    using System.Data;
    using System.Data.SqlClient;
    using System.Activities;
    using System.Activities.DynamicUpdate;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Activities.DurableInstancing;
    
  15. Dodaj następujący element członkowski parametry połączenia do Program klasy (lub Module1).

    Const connectionString = "Server=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=SSPI"
    
    const string connectionString = "Server=.\\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=SSPI";
    

    Ważne

    Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Jeśli łączysz się z usługą Azure SQL, tożsamości zarządzane dla zasobów platformy Azure to zalecana metoda uwierzytelniania.

    Uwaga

    W zależności od wersji programu SQL Server nazwa serwera parametry połączenia może być inna.

  16. Dodaj następującą GetIDs metodę do Program klasy (lub Module1). Ta metoda zwraca listę identyfikatorów utrwalonego wystąpienia przepływu pracy.

    Function GetIds() As IList(Of Guid)
        Dim Ids As New List(Of Guid)
        Dim localCmd = _
            String.Format("Select [InstanceId] from [System.Activities.DurableInstancing].[Instances] Order By [CreationTime]")
        Using localCon = New SqlConnection(connectionString)
            Dim cmd As SqlCommand = localCon.CreateCommand()
            cmd.CommandText = localCmd
            localCon.Open()
            Using reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
                While reader.Read()
                    'Get the InstanceId of the persisted Workflow
                    Dim id As Guid = Guid.Parse(reader(0).ToString())
    
                    'Add it to the list.
                    Ids.Add(id)
                End While
            End Using
        End Using
    
        Return Ids
    End Function
    
    static IList<Guid> GetIds()
    {
        List<Guid> Ids = new List<Guid>();
        string localCmd = string.Format("Select [InstanceId] from [System.Activities.DurableInstancing].[Instances] Order By [CreationTime]");
        using (SqlConnection localCon = new SqlConnection(connectionString))
        {
            SqlCommand cmd = localCon.CreateCommand();
            cmd.CommandText = localCmd;
            localCon.Open();
            using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                while (reader.Read())
                {
                    // Get the InstanceId of the persisted Workflow
                    Guid id = Guid.Parse(reader[0].ToString());
    
                    // Add it to the list.
                    Ids.Add(id);
                }
            }
        }
    
        return Ids;
    }
    
  17. Dodaj następującą LoadMap metodę do Program klasy (lub Module1). Ta metoda tworzy słownik, który mapuje v1 tożsamości przepływu pracy na mapy aktualizacji i nowe tożsamości przepływu pracy używane do aktualizowania odpowiednich trwałych wystąpień przepływu pracy.

    Function LoadMap(mapName As String) As DynamicUpdateMap
        Dim mapPath As String = Path.Combine("..\..\..\PreviousVersions", mapName)
    
        Dim map As DynamicUpdateMap
        Using fs As FileStream = File.Open(mapPath, FileMode.Open)
            Dim serializer As DataContractSerializer = New DataContractSerializer(GetType(DynamicUpdateMap))
            Dim updateMap = serializer.ReadObject(fs)
            If updateMap Is Nothing Then
                Throw New ApplicationException("DynamicUpdateMap is null.")
            End If
    
            map = updateMap
        End Using
    
        Return map
    End Function
    
    static DynamicUpdateMap LoadMap(string mapName)
    {
        string path = Path.Combine(@"..\..\..\PreviousVersions", mapName);
    
        DynamicUpdateMap map;
        using (FileStream fs = File.Open(path, FileMode.Open))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
            object updateMap = serializer.ReadObject(fs);
            if (updateMap == null)
            {
                throw new ApplicationException("DynamicUpdateMap is null.");
            }
    
            map = updateMap as DynamicUpdateMap;
        }
    
        return map;
    }
    
  18. Dodaj następującą LoadMaps metodę do Program klasy (lub Module1). Ta metoda ładuje trzy mapy aktualizacji i tworzy słownik, który mapuje v1 tożsamości przepływu pracy na mapy aktualizacji.

    Function LoadMaps() As IDictionary(Of WorkflowIdentity, DynamicUpdateInfo)
        'There are 3 update maps to describe the changes to update v1 workflows,
        'one for reach of the 3 workflow types in the tutorial.
        Dim maps = New Dictionary(Of WorkflowIdentity, DynamicUpdateInfo)()
    
        Dim sequentialMap As DynamicUpdateMap = LoadMap("SequentialNumberGuessWorkflow.map")
        Dim sequentialInfo = New DynamicUpdateInfo With
        {
            .updateMap = sequentialMap,
            .newIdentity = WorkflowVersionMap.SequentialNumberGuessIdentity_v15
        }
        maps.Add(WorkflowVersionMap.SequentialNumberGuessIdentity_v1, sequentialInfo)
    
        Dim stateMap As DynamicUpdateMap = LoadMap("StateMachineNumberGuessWorkflow.map")
        Dim stateInfo = New DynamicUpdateInfo With
        {
            .updateMap = stateMap,
            .newIdentity = WorkflowVersionMap.StateMachineNumberGuessIdentity_v15
        }
        maps.Add(WorkflowVersionMap.StateMachineNumberGuessIdentity_v1, stateInfo)
    
        Dim flowchartMap As DynamicUpdateMap = LoadMap("FlowchartNumberGuessWorkflow.map")
        Dim flowchartInfo = New DynamicUpdateInfo With
        {
            .updateMap = flowchartMap,
            .newIdentity = WorkflowVersionMap.FlowchartNumberGuessIdentity_v15
        }
        maps.Add(WorkflowVersionMap.FlowchartNumberGuessIdentity_v1, flowchartInfo)
    
        Return maps
    End Function
    
    static IDictionary<WorkflowIdentity, DynamicUpdateInfo> LoadMaps()
    {
        // There are 3 update maps to describe the changes to update v1 workflows,
        // one for reach of the 3 workflow types in the tutorial.
        Dictionary<WorkflowIdentity, DynamicUpdateInfo> maps =
            new Dictionary<WorkflowIdentity, DynamicUpdateInfo>();
    
        DynamicUpdateMap sequentialMap = LoadMap("SequentialNumberGuessWorkflow.map");
        DynamicUpdateInfo sequentialInfo = new DynamicUpdateInfo
        {
            updateMap = sequentialMap,
            newIdentity = WorkflowVersionMap.SequentialNumberGuessIdentity_v15
        };
        maps.Add(WorkflowVersionMap.SequentialNumberGuessIdentity_v1, sequentialInfo);
    
        DynamicUpdateMap stateMap = LoadMap("StateMachineNumberGuessWorkflow.map");
        DynamicUpdateInfo stateInfo = new DynamicUpdateInfo
        {
            updateMap = stateMap,
            newIdentity = WorkflowVersionMap.StateMachineNumberGuessIdentity_v15
        };
        maps.Add(WorkflowVersionMap.StateMachineNumberGuessIdentity_v1, stateInfo);
    
        DynamicUpdateMap flowchartMap = LoadMap("FlowchartNumberGuessWorkflow.map");
        DynamicUpdateInfo flowchartInfo = new DynamicUpdateInfo
        {
            updateMap = flowchartMap,
            newIdentity = WorkflowVersionMap.FlowchartNumberGuessIdentity_v15
        };
        maps.Add(WorkflowVersionMap.FlowchartNumberGuessIdentity_v1, flowchartInfo);
    
        return maps;
    }
    
  19. Dodaj następujący kod do pliku Main. Ten kod iteruje utrwalone wystąpienia przepływu pracy i sprawdza każdy WorkflowIdentityelement . Jeśli mapuje WorkflowIdentity się na v1 wystąpienie przepływu pracy, WorkflowApplication element jest skonfigurowany ze zaktualizowaną definicją przepływu pracy i zaktualizowaną tożsamością przepływu pracy. WorkflowApplication.Load Następnie jest wywoływana z wystąpieniem i mapą aktualizacji, która stosuje mapę aktualizacji dynamicznej. Po zastosowaniu aktualizacji zaktualizowane wystąpienie jest utrwalane za pomocą wywołania metody Unload.

    Dim store = New SqlWorkflowInstanceStore(connectionString)
    WorkflowApplication.CreateDefaultInstanceOwner(store, Nothing, WorkflowIdentityFilter.Any)
    
    Dim updateMaps As IDictionary(Of WorkflowIdentity, DynamicUpdateInfo) = LoadMaps()
    
    For Each id As Guid In GetIds()
        'Get a proxy to the instance.
        Dim instance As WorkflowApplicationInstance = WorkflowApplication.GetInstance(id, store)
    
        Console.WriteLine("Inspecting: {0}", instance.DefinitionIdentity)
    
        'Only update v1 workflows.
        If Not instance.DefinitionIdentity Is Nothing AndAlso _
            instance.DefinitionIdentity.Version.Equals(New Version(1, 0, 0, 0)) Then
    
            Dim info As DynamicUpdateInfo = updateMaps(instance.DefinitionIdentity)
    
            'Associate the persisted WorkflowApplicationInstance with
            'a WorkflowApplication that is configured with the updated
            'definition and updated WorkflowIdentity.
            Dim wf As Activity = WorkflowVersionMap.GetWorkflowDefinition(info.newIdentity)
            Dim wfApp = New WorkflowApplication(wf, info.newIdentity)
    
            'Apply the Dynamic Update.
            wfApp.Load(instance, info.updateMap)
    
            'Persist the updated instance.
            wfApp.Unload()
    
            Console.WriteLine("Updated to: {0}", info.newIdentity)
        Else
            'Not updating this instance, so unload it.
            instance.Abandon()
        End If
    Next
    
    SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(connectionString);
    WorkflowApplication.CreateDefaultInstanceOwner(store, null, WorkflowIdentityFilter.Any);
    
    IDictionary<WorkflowIdentity, DynamicUpdateInfo> updateMaps = LoadMaps();
    
    foreach (Guid id in GetIds())
    {
        // Get a proxy to the instance.
        WorkflowApplicationInstance instance =
            WorkflowApplication.GetInstance(id, store);
    
        Console.WriteLine("Inspecting: {0}", instance.DefinitionIdentity);
    
        // Only update v1 workflows.
        if (instance.DefinitionIdentity != null &&
            instance.DefinitionIdentity.Version.Equals(new Version(1, 0, 0, 0)))
        {
            DynamicUpdateInfo info = updateMaps[instance.DefinitionIdentity];
    
            // Associate the persisted WorkflowApplicationInstance with
            // a WorkflowApplication that is configured with the updated
            // definition and updated WorkflowIdentity.
            Activity wf = WorkflowVersionMap.GetWorkflowDefinition(info.newIdentity);
            WorkflowApplication wfApp =
                new WorkflowApplication(wf, info.newIdentity);
    
            // Apply the Dynamic Update.
            wfApp.Load(instance, info.updateMap);
    
            // Persist the updated instance.
            wfApp.Unload();
    
            Console.WriteLine("Updated to: {0}", info.newIdentity);
        }
        else
        {
            // Not updating this instance, so unload it.
            instance.Abandon();
        }
    }
    
  20. Kliknij prawym przyciskiem myszy pozycję ApplyDynamicUpdate w Eksplorator rozwiązań i wybierz polecenie Ustaw jako projekt startowy.

  21. Naciśnij Ctrl+Shift+B, aby skompilować rozwiązanie, a następnie naciśnij Ctrl+F5, aby uruchomić aplikację ApplyDynamicUpdate i zaktualizować utrwalone wystąpienia przepływu pracy. Wyświetlone dane wyjściowe powinny wyglądać mniej więcej tak. Przepływy pracy w wersji 1.0.0.0 są aktualizowane do wersji 1.5.0.0, podczas gdy przepływy pracy w wersji 2.0.0.0 nie są aktualizowane.

    Inspekcja: StateMachineNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: StateMachineNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: StateMachineNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: StateMachineNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: Schemat blokowyNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: Schemat blokowyNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: Schemat blokowyNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: Schemat blokowyNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: SekwencyjneNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: SekwencyjneNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: SekwencyjneNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: SekwencyjneNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: SekwencyjneNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: SekwencyjneNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: StateMachineNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: StateMachineNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: Schemat blokowyNumberGuessWorkflow; Wersja=1.0.0.0
    Zaktualizowano do: Schemat blokowyNumberGuessWorkflow; Wersja=1.5.0.0
    Inspekcja: StateMachineNumberGuessWorkflow; Wersja=2.0.0.0
    Inspekcja: StateMachineNumberGuessWorkflow; Wersja=2.0.0.0
    Inspekcja: Schemat blokowyNumberGuessWorkflow; Wersja=2.0.0.0
    Inspekcja: Schemat blokowyNumberGuessWorkflow; Wersja=2.0.0.0
    Inspekcja: SekwencyjneNumberGuessWorkflow; Wersja=2.0.0.0
    Inspekcja: SekwencyjneNumberGuessWorkflow; Wersja=2.0.0.0
    Naciśnij dowolny, aby kontynuować . . .

Aby uruchomić aplikację ze zaktualizowanymi przepływami pracy

  1. Kliknij prawym przyciskiem myszy pozycję NumberGuessWorkflowHost w Eksplorator rozwiązań i wybierz polecenie Ustaw jako projekt startowy.

  2. Naciśnij klawisze CTRL+F5, aby uruchomić aplikację.

  3. Kliknij pozycję Nowa gra , aby rozpocząć nowy przepływ pracy i zanotuj informacje o wersji poniżej okna stanu, które wskazuje, że przepływ pracy jest przepływem v2 pracy.

  4. Wybierz jeden z v1 przepływów pracy uruchomionych na początku tematu Instrukcje: hostowanie wielu wersji przepływu pracy obok siebie . Należy pamiętać, że informacje o wersji w oknie stanu wskazują, że przepływ pracy jest przepływem pracy w wersji 1.5.0.0 . Należy pamiętać, że nie ma żadnych informacji na temat poprzednich zgadywania innych niż to, czy były zbyt wysokie, czy zbyt niskie.

    Wprowadź liczbę z zakresu od 1 do 10
    Twoje zgadywanie jest zbyt niskie.

  5. Zanotuj wartości , InstanceId a następnie wprowadź odgadnięcia do momentu zakończenia przepływu pracy. W oknie stanu są wyświetlane informacje o zawartości odgadnięcia, ponieważ WriteLine działania zostały zaktualizowane przez aktualizację dynamiczną.

    Wprowadź liczbę z zakresu od 1 do 10
    Twoje zgadywanie jest zbyt niskie.
    Wprowadź liczbę z zakresu od 1 do 10
    5 jest zbyt niskie.
    Wprowadź liczbę z zakresu od 1 do 10
    7 jest zbyt wysokie.
    Wprowadź liczbę z zakresu od 1 do 10
    Gratulacje, odgadłeś liczbę w 4 zakrętach.

  6. 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 Notatnika odpowiadającego ukończonego przepływu pracy. Jeśli nie zanotujesz pliku InstanceId śledzenia, możesz zidentyfikować prawidłowy plik śledzenia przy użyciu informacji zmodyfikowanych daty w Eksploratorze Windows. Ostatni wiersz informacji o śledzeniu zawiera dane wyjściowe nowo dodanego WriteLine działania.

    Wprowadź liczbę z zakresu od 1 do 10
    Twoje zgadywanie jest zbyt niskie.
    Wprowadź liczbę z zakresu od 1 do 10
    5 jest zbyt niskie.
    Wprowadź liczbę z zakresu od 1 do 10
    7 jest zbyt wysokie.
    Wprowadź liczbę z zakresu od 1 do 10
    6 jest poprawne. Domyśliłeś się, że to na 4 zakręty.

Aby włączyć uruchamianie poprzednich wersji przepływów pracy

Jeśli zabraknie przepływów pracy do zaktualizowania, możesz zmodyfikować aplikację NumberGuessWorkflowHost , aby włączyć uruchamianie poprzednich wersji przepływów pracy.

  1. Kliknij dwukrotnie element WorkflowHostForm w Eksplorator rozwiązań i wybierz pole kombi WorkflowType.

  2. W oknie Właściwości wybierz właściwość Items i kliknij przycisk wielokropka, aby edytować kolekcję Items.

  3. Dodaj następujące trzy elementy do kolekcji.

    StateMachineNumberGuessWorkflow v1
    FlowchartNumberGuessWorkflow v1
    SequentialNumberGuessWorkflow v1
    

    Ukończona Items kolekcja będzie miała sześć elementów.

    StateMachineNumberGuessWorkflow
    FlowchartNumberGuessWorkflow
    SequentialNumberGuessWorkflow
    StateMachineNumberGuessWorkflow v1
    FlowchartNumberGuessWorkflow v1
    SequentialNumberGuessWorkflow v1
    
  4. Kliknij dwukrotnie element WorkflowHostForm w Eksplorator rozwiązań, a następnie wybierz pozycję Wyświetl kod.

  5. Dodaj trzy nowe przypadki do instrukcji switch (lub Select Case) w procedurze NewGame_Click obsługi, aby zamapować nowe elementy w polu kombi WorkflowType na pasujące tożsamości przepływu pracy.

    Case "SequentialNumberGuessWorkflow v1"
        identity = WorkflowVersionMap.SequentialNumberGuessIdentity_v1
    
    Case "StateMachineNumberGuessWorkflow v1"
        identity = WorkflowVersionMap.StateMachineNumberGuessIdentity_v1
    
    Case "FlowchartNumberGuessWorkflow v1"
        identity = WorkflowVersionMap.FlowchartNumberGuessIdentity_v1
    
    case "SequentialNumberGuessWorkflow v1":
        identity = WorkflowVersionMap.SequentialNumberGuessIdentity_v1;
        break;
    
    case "StateMachineNumberGuessWorkflow v1":
        identity = WorkflowVersionMap.StateMachineNumberGuessIdentity_v1;
        break;
    
    case "FlowchartNumberGuessWorkflow v1":
        identity = WorkflowVersionMap.FlowchartNumberGuessIdentity_v1;
        break;
    

    Poniższy przykład zawiera kompletną switch instrukcję (lub Select Case).

    Select Case WorkflowType.SelectedItem.ToString()
        Case "SequentialNumberGuessWorkflow"
            identity = WorkflowVersionMap.SequentialNumberGuessIdentity
    
        Case "StateMachineNumberGuessWorkflow"
            identity = WorkflowVersionMap.StateMachineNumberGuessIdentity
    
        Case "FlowchartNumberGuessWorkflow"
            identity = WorkflowVersionMap.FlowchartNumberGuessIdentity
    
        Case "SequentialNumberGuessWorkflow v1"
            identity = WorkflowVersionMap.SequentialNumberGuessIdentity_v1
    
        Case "StateMachineNumberGuessWorkflow v1"
            identity = WorkflowVersionMap.StateMachineNumberGuessIdentity_v1
    
        Case "FlowchartNumberGuessWorkflow v1"
            identity = WorkflowVersionMap.FlowchartNumberGuessIdentity_v1
    End Select
    
    switch (WorkflowType.SelectedItem.ToString())
    {
        case "SequentialNumberGuessWorkflow":
            identity = WorkflowVersionMap.SequentialNumberGuessIdentity;
            break;
    
        case "StateMachineNumberGuessWorkflow":
            identity = WorkflowVersionMap.StateMachineNumberGuessIdentity;
            break;
    
        case "FlowchartNumberGuessWorkflow":
            identity = WorkflowVersionMap.FlowchartNumberGuessIdentity;
            break;
    
        case "SequentialNumberGuessWorkflow v1":
            identity = WorkflowVersionMap.SequentialNumberGuessIdentity_v1;
            break;
    
        case "StateMachineNumberGuessWorkflow v1":
            identity = WorkflowVersionMap.StateMachineNumberGuessIdentity_v1;
            break;
    
        case "FlowchartNumberGuessWorkflow v1":
            identity = WorkflowVersionMap.FlowchartNumberGuessIdentity_v1;
            break;
    };
    
  6. Naciśnij CTRL+F5, aby skompilować i uruchomić aplikację. Teraz możesz uruchomić v1 wersje przepływu pracy, a także bieżące wersje. Aby dynamicznie aktualizować te nowe wystąpienia, uruchom aplikację ApplyDynamicUpdate .