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.
Dynamisk uppdatering
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.
Uppdatera arbetsflödesdefinitionen så att den återspeglar önskade ändringar
Tillämpa uppdateringskartan på önskade bevarade arbetsflödesinstanser
Kommentar
Observera att steg 1 till och med 3, som omfattar skapandet av uppdateringskartan, kan utföras oberoende av hur uppdateringen tillämpas. Ett vanligt scenario där arbetsflödesutvecklaren skapar uppdateringskartan offline och sedan tillämpar en administratör uppdateringen vid ett senare tillfälle.
Det här avsnittet 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.
Kommentar
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 förbereds sedan för dynamisk uppdatering. När metoden har returnerats ActivityBuilder innehåller 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 ett löpande ombud. Dessa ändringar kan göras med hjälp av kod eller i en omvärderad arbetsflödesdesigner. I följande exempel läggs en anpassad VerifyAppraisal
aktivitet till i sekvensen som utgör brödtexten i MortgageWorkflow
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 som körningen behöver för att ändra en instans av ett beständiga arbetsflöde så att den kan läsas in 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 när som helst tillämpa uppdateringskartan när som helst när 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 läser du in den i en WorkflowApplicationInstance med .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 har WorkflowApplication skapats läses den in med hjälp av överlagringen av WorkflowApplication.Load som tar en DynamicUpdateMap, och sedan tas bort 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.
Kommentar
Mer information om hur du arbetar med WorkflowApplication och finns i Använda WorkflowIdentity och VersionshanteringWorkflowIdentity.
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(...);