Dela via


Dynamisk uppdatering

Dynamisk uppdatering ger en mekanism för utvecklare av arbetsflödesprogram för att uppdatera arbetsflödesdefinitionen för en instans av ett sparat arbetsflöde. Detta kan vara att implementera en felkorrigering, nya krav eller för att hantera oväntade ändringar. Det här avsnittet innehåller en översikt över de dynamiska uppdateringsfunktioner som introducerades i .NET Framework 4.5.

Om du vill tillämpa dynamiska uppdateringar på en instans av ett beständiga arbetsflöde skapas en DynamicUpdateMap som innehåller instruktioner för körningen som beskriver hur du ändrar den bevarade arbetsflödesinstansen för att återspegla önskade ändringar. När uppdateringskartan har skapats tillämpas den på önskade bevarade arbetsflödesinstanser. När den dynamiska uppdateringen har tillämpats kan arbetsflödesinstansen återupptas med den nya uppdaterade arbetsflödesdefinitionen. Det krävs fyra steg för att skapa och tillämpa en uppdateringskarta.

  1. Förbered arbetsflödesdefinitionen för dynamisk uppdatering.
  2. Uppdatera arbetsflödesdefinitionen så att den återspeglar önskade ändringar.
  3. Skapa uppdateringskartan.
  4. Använd uppdateringskartan på önskade instanser av det bevarade arbetsflödet.

Anmärkning

Steg 1 till och med 3, som omfattar skapandet av uppdateringskartan, kan utföras oberoende av hur uppdateringen tillämpas. Ett vanligt scenario är att arbetsflödesutvecklaren skapar uppdateringskartan offline och sedan tillämpar en administratör uppdateringen vid ett senare tillfälle.

Den här artikeln innehåller en översikt över den dynamiska uppdateringsprocessen för att lägga till en ny aktivitet i en bevarad instans av ett kompilerat Xaml-arbetsflöde.

Förbereda arbetsflödesdefinitionen för dynamisk uppdatering

Det första steget i den dynamiska uppdateringsprocessen är att förbereda den önskade arbetsflödesdefinitionen för uppdatering. Detta görs genom att anropa DynamicUpdateServices.PrepareForUpdate metoden och skicka in arbetsflödesdefinitionen för att ändra. Den här metoden validerar och vägleder sedan arbetsflödesträdet för att identifiera alla objekt, till exempel offentliga aktiviteter och variabler som måste taggas så att de kan jämföras senare med den ändrade arbetsflödesdefinitionen. När det här är klart klonas arbetsflödesträdet och kopplas till den ursprungliga arbetsflödesdefinitionen. När uppdateringskartan skapas jämförs den uppdaterade versionen av arbetsflödesdefinitionen med den ursprungliga arbetsflödesdefinitionen och uppdateringskartan genereras baserat på skillnaderna.

För att förbereda ett Xaml-arbetsflöde för dynamisk uppdatering kan det läsas in i en ActivityBuilder, och sedan skickas det ActivityBuilder till DynamicUpdateServices.PrepareForUpdate.

Anmärkning

Mer information om hur du arbetar med serialiserade arbetsflöden och ActivityBuilderfinns i Serialisera arbetsflöden och aktiviteter till och från XAML.

I följande exempel läses en MortgageWorkflow-definition (som består av en Sequence med flera underordnade aktiviteter) in i en ActivityBuilder, och definitionen förbereds sedan för dynamisk uppdatering. När metoden har körts klart innehåller ActivityBuilder den ursprungliga arbetsflödesdefinitionen samt en kopia.

// Load the MortgageWorkflow definition from Xaml into
// an ActivityBuilder.
XamlXmlReaderSettings readerSettings = new XamlXmlReaderSettings()
{
    LocalAssembly = Assembly.GetExecutingAssembly()
};

XamlXmlReader xamlReader = new XamlXmlReader(@"C:\WorkflowDefinitions\MortgageWorkflow.xaml",
    readerSettings);

ActivityBuilder ab = XamlServices.Load(
    ActivityXamlServices.CreateBuilderReader(xamlReader)) as ActivityBuilder;

// Prepare the workflow definition for dynamic update.
DynamicUpdateServices.PrepareForUpdate(ab);

Uppdatera arbetsflödesdefinitionen så att den återspeglar önskade ändringar

När arbetsflödesdefinitionen har förberetts för uppdatering kan önskade ändringar göras. Du kan lägga till eller ta bort aktiviteter, lägga till, flytta eller ta bort offentliga variabler, lägga till eller ta bort argument och göra ändringar i signaturen för aktivitetsdelegater. Du kan inte ta bort en aktivitet som körs eller ändra signaturen för en körande delegat. Dessa ändringar kan göras med hjälp av kod eller i en omhostad arbetsflödesdesigner. I följande exempel läggs en anpassad VerifyAppraisal-aktivitet till sekvensen som utgör huvuddelen av MortgageWorkflow i föregående exempel.

// Make desired changes to the definition. In this example, we are
// inserting a new VerifyAppraisal activity as the 3rd child of the root Sequence.
VerifyAppraisal va = new VerifyAppraisal
{
    Result = new VisualBasicReference<bool>("LoanCriteria")
};

// Get the Sequence that makes up the body of the workflow.
Sequence s = ab.Implementation as Sequence;

// Insert the new activity into the Sequence.
s.Activities.Insert(2, va);

Skapa uppdateringskartan

När arbetsflödesdefinitionen som förbereddes för uppdatering har ändrats kan uppdateringskartan skapas. För att skapa en dynamisk uppdateringskarta DynamicUpdateServices.CreateUpdateMap anropas metoden. Detta returnerar en DynamicUpdateMap som innehåller den information körtiden behöver för att ändra en beständig arbetsflödesinstans så att den kan laddas och återupptas med den nya arbetsflödesdefinitionen. I följande exempel skapas en dynamisk karta för den ändrade MortgageWorkflow definitionen från föregående exempel.

// Create the update map.
DynamicUpdateMap map = DynamicUpdateServices.CreateUpdateMap(ab);

Den här uppdateringskartan kan omedelbart användas för att ändra instanser av bevarade arbetsflöden, eller mer normalt kan den sparas och uppdateringarna tillämpas senare. Ett sätt att spara uppdateringskartan är att serialisera den till en fil, som du ser i följande exempel.

// Serialize the update map to a file.
DataContractSerializer serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
using (FileStream fs = System.IO.File.Open(@"C:\WorkflowDefinitions\MortgageWorkflow.map", FileMode.Create))
{
    serializer.WriteObject(fs, map);
}

När DynamicUpdateServices.CreateUpdateMap returneras tas den klonade arbetsflödesdefinitionen och annan dynamisk uppdateringsinformation som lades till i anropet till DynamicUpdateServices.PrepareForUpdate bort, och den ändrade arbetsflödesdefinitionen är redo att sparas så att den kan användas senare när du återupptar uppdaterade arbetsflödesinstanser. I följande exempel sparas den ändrade arbetsflödesdefinitionen till MortgageWorkflow_v1.1.xaml.

// Save the modified workflow definition.
StreamWriter sw = File.CreateText(@"C:\WorkflowDefinitions\MortgageWorkflow_v1.1.xaml");
XamlWriter xw = ActivityXamlServices.CreateBuilderWriter(new XamlXmlWriter(sw, new XamlSchemaContext()));
XamlServices.Save(xw, ab);
sw.Close();

Tillämpa uppdateringskartan på önskade bevarade arbetsflödesinstanser

Du kan tillämpa uppdateringskartan när som helst efter att du har skapat den. Det kan göras direkt med den DynamicUpdateMap instans som returnerades av DynamicUpdateServices.CreateUpdateMap, eller så kan det göras senare med hjälp av en sparad kopia av uppdateringskartan. Om du vill uppdatera en arbetsflödesinstans, ladda in den i en WorkflowApplicationInstance med hjälp av WorkflowApplication.GetInstance. Skapa sedan en WorkflowApplication med den uppdaterade arbetsflödesdefinitionen och önskad WorkflowIdentity. Detta WorkflowIdentity kan skilja sig från det som användes för att bevara det ursprungliga arbetsflödet och är vanligtvis för att återspegla att den bevarade instansen har ändrats. När WorkflowApplication har skapats, läses den in med hjälp av överlagringen av WorkflowApplication.Load som tar en DynamicUpdateMap, och sedan läses den ut med ett anrop till WorkflowApplication.Unload. Detta tillämpar den dynamiska uppdateringen och bevarar den uppdaterade arbetsflödesinstansen.

// Load the serialized update map.
DynamicUpdateMap map;
using (FileStream fs = File.Open(@"C:\WorkflowDefinitions\MortgageWorkflow.map", FileMode.Open))
{
    DataContractSerializer serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
    object updateMap = serializer.ReadObject(fs);
    if (updateMap == null)
    {
        throw new ApplicationException("DynamicUpdateMap is null.");
    }

    map = (DynamicUpdateMap)updateMap;
}

// Retrieve a list of workflow instance ids that corresponds to the
// workflow instances to update. This step is the responsibility of
// the application developer.
List<Guid> ids = GetPersistedWorkflowIds();
foreach (Guid id in ids)
{
    // Get a proxy to the persisted workflow instance.
    SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(connectionString);
    WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(id, store);

    // If desired, you can inspect the WorkflowIdentity of the instance
    // using the DefinitionIdentity property to determine whether to apply
    // the update.
    Console.WriteLine(instance.DefinitionIdentity);

    // Create a workflow application. You must specify the updated workflow definition, and
    // you may provide an updated WorkflowIdentity if desired to reflect the update.
    WorkflowIdentity identity = new WorkflowIdentity
    {
        Name = "MortgageWorkflow v1.1",
        Version = new Version(1, 1, 0, 0)
    };

    // Load the persisted workflow instance using the updated workflow definition
    // and with an updated WorkflowIdentity. In this example the MortgageWorkflow class
    // contains the updated definition.
    WorkflowApplication wfApp = new WorkflowApplication(new MortgageWorkflow(), identity);

    // Apply the dynamic update on the loaded instance.
    wfApp.Load(instance, map);

    // Unload the updated instance.
    wfApp.Unload();
}

Återuppta en uppdaterad arbetsflödesinstans

När dynamisk uppdatering har tillämpats kan arbetsflödesinstansen återupptas. Observera att den nya uppdaterade definitionen och WorkflowIdentity måste användas.

Anmärkning

Mer information om hur du arbetar med WorkflowApplication och WorkflowIdentityfinns i Använda WorkflowIdentity och Versionshantering.

I följande exempel MortgageWorkflow_v1.1.xaml har arbetsflödet från föregående exempel kompilerats och läses in och återupptas med den uppdaterade arbetsflödesdefinitionen.

// Load the persisted workflow instance using the updated workflow definition
// and updated WorkflowIdentity.
WorkflowIdentity identity = new WorkflowIdentity
{
    Name = "MortgageWorkflow v1.1",
    Version = new Version(1, 1, 0, 0)
};

WorkflowApplication wfApp = new WorkflowApplication(new MortgageWorkflow(), identity);

// Configure persistence and desired workflow event handlers.
// (Omitted for brevity.)
ConfigureWorkflowApplication(wfApp);

// Load the persisted workflow instance.
wfApp.Load(InstanceId);

// Resume the workflow.
// wfApp.ResumeBookmark(...);