Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'aggiornamento dinamico fornisce un meccanismo per gli sviluppatori di applicazioni per flussi di lavoro per aggiornare la definizione di un'istanza persistente del flusso di lavoro. Può trattarsi di implementare una correzione di bug, nuovi requisiti o per soddisfare modifiche impreviste. Questo argomento offre una panoramica delle funzionalità di aggiornamento dinamico introdotte in .NET Framework 4.5.
Per applicare gli aggiornamenti dinamici a un'istanza del flusso di lavoro persistente, viene creato un oggetto DynamicUpdateMap che contiene istruzioni per il runtime che descrivono come modificare l'istanza del flusso di lavoro persistente in modo da riflettere le modifiche desiderate. Dopo aver creato la mappa di aggiornamento, viene applicata alle istanze del flusso di lavoro persistenti desiderate. Dopo l'applicazione dell'aggiornamento dinamico, l'istanza del flusso di lavoro può essere ripresa usando la nuova definizione aggiornata del flusso di lavoro. Sono necessari quattro passaggi per creare e applicare una mappa di aggiornamento.
- Preparare la definizione del flusso di lavoro per l'aggiornamento dinamico.
- Aggiornare la definizione del flusso di lavoro in modo da riflettere le modifiche desiderate.
- Creare la mappa di aggiornamento.
- Applicare la mappa di aggiornamento alle istanze del flusso di lavoro persistenti desiderate.
Annotazioni
I passaggi da 1 a 3, che coprono la creazione della mappa di aggiornamento, possono essere eseguiti indipendentemente dall'applicazione dell'aggiornamento. Uno scenario comune è che lo sviluppatore del flusso di lavoro creerà la mappa di aggiornamento offline e quindi un amministratore applicherà l'aggiornamento in un secondo momento.
Questo articolo offre una panoramica del processo di aggiornamento dinamico dell'aggiunta di una nuova attività a un'istanza persistente di un flusso di lavoro Xaml compilato.
Preparare la definizione del flusso di lavoro per l'aggiornamento dinamico
Il primo passaggio del processo di aggiornamento dinamico consiste nel preparare la definizione del flusso di lavoro desiderata per l'aggiornamento. A tale scopo, chiamare il DynamicUpdateServices.PrepareForUpdate metodo e passare la definizione del flusso di lavoro da modificare. Questo metodo convalida e quindi analizza l'albero del flusso di lavoro per identificare tutti gli oggetti, ad esempio le attività pubbliche e le variabili che devono essere contrassegnate, in modo che possano essere confrontati in un secondo momento con la definizione del flusso di lavoro modificata. Al termine, l'albero del flusso di lavoro viene clonato e collegato alla definizione originale del flusso di lavoro. Quando viene creata la mappa di aggiornamento, la versione aggiornata della definizione del flusso di lavoro viene confrontata con la definizione del flusso di lavoro originale e la mappa di aggiornamento viene generata in base alle differenze.
Per preparare un flusso di lavoro Xaml per l'aggiornamento dinamico, può essere caricato in un ActivityBuilder, e quindi ActivityBuilder viene passato a DynamicUpdateServices.PrepareForUpdate.
Annotazioni
Per altre informazioni sull'uso di flussi di lavoro serializzati e ActivityBuilder, vedere Serializzazione di flussi di lavoro e attività da e verso XAML.
Nell'esempio seguente una MortgageWorkflow definizione (costituita da un Sequence elemento con diverse attività figlio) viene caricata in un ActivityBuilder oggetto e quindi preparata per l'aggiornamento dinamico. Dopo che il metodo restituisce, ActivityBuilder contiene la definizione originale del flusso di lavoro e una copia.
// 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);
Aggiornare la definizione del flusso di lavoro in modo da riflettere le modifiche desiderate
Dopo aver preparato la definizione del flusso di lavoro per l'aggiornamento, è possibile apportare le modifiche desiderate. È possibile aggiungere o rimuovere attività, aggiungere, spostare o eliminare variabili pubbliche, aggiungere o rimuovere argomenti e apportare modifiche alla firma dei delegati di attività. Non è possibile rimuovere un'attività in esecuzione o modificare la firma di un delegato in esecuzione. Queste modifiche possono essere apportate usando il codice o in una finestra di progettazione del flusso di lavoro ospitata di nuovo. Nell'esempio seguente viene aggiunta un'attività personalizzata VerifyAppraisal alla sequenza che costituisce il corpo dell'oggetto MortgageWorkflow dell'esempio precedente.
// 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);
Creare la mappa di aggiornamento
Dopo aver modificato la definizione del flusso di lavoro preparata per l'aggiornamento, è possibile creare la mappa di aggiornamento. Per creare una mappa di aggiornamento dinamico, viene richiamato il DynamicUpdateServices.CreateUpdateMap metodo . Restituisce un oggetto DynamicUpdateMap contenente le informazioni necessarie al runtime per modificare un'istanza del flusso di lavoro persistente in modo che possa essere caricata e ripresa con la nuova definizione del flusso di lavoro. Nell'esempio seguente viene creata una mappa dinamica per la definizione modificata MortgageWorkflow dell'esempio precedente.
// Create the update map.
DynamicUpdateMap map = DynamicUpdateServices.CreateUpdateMap(ab);
Questa mappa di aggiornamento può essere usata immediatamente per modificare le istanze del flusso di lavoro persistenti o in genere può essere salvata e gli aggiornamenti applicati in un secondo momento. Un modo per salvare la mappa di aggiornamento consiste nel serializzarlo in un file, come illustrato nell'esempio seguente.
// 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);
}
Quando DynamicUpdateServices.CreateUpdateMap termina, la definizione del flusso di lavoro clonata e altre informazioni sull'aggiornamento dinamico aggiunte nella chiamata a DynamicUpdateServices.PrepareForUpdate viene rimossa e la definizione del flusso di lavoro modificata è pronta per essere salvata in modo che possa essere usata in un secondo momento durante la ripresa delle istanze aggiornate del flusso di lavoro. Nell'esempio seguente la definizione del flusso di lavoro modificata viene salvata in 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();
Applicare la mappa di aggiornamento alle istanze del flusso di lavoro persistenti desiderate
L'applicazione della mappa di aggiornamento può essere eseguita in qualsiasi momento dopo la creazione. Può essere eseguita immediatamente usando l'istanza DynamicUpdateMap restituita da DynamicUpdateServices.CreateUpdateMapoppure può essere eseguita in un secondo momento usando una copia salvata della mappa di aggiornamento. Per aggiornare un'istanza del flusso di lavoro, caricarla in un oggetto WorkflowApplicationInstance usando WorkflowApplication.GetInstance. Crea quindi un WorkflowApplication utilizzando la definizione aggiornata del flusso di lavoro e il WorkflowIdentity desiderato. Questo WorkflowIdentity può essere diverso da quello usato per rendere persistente il flusso di lavoro originale e in genere è per riflettere che l'istanza persistente è stata modificata. Una volta creato WorkflowApplication, viene caricato usando l'overload di WorkflowApplication.Load che accetta un DynamicUpdateMap oggetto e quindi scaricato con una chiamata a WorkflowApplication.Unload. In questo modo viene applicato l'aggiornamento dinamico e viene mantenuta l'istanza aggiornata del flusso di lavoro.
// 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();
}
Ripristinare un'istanza del flusso di lavoro aggiornata
Dopo l'applicazione dell'aggiornamento dinamico, l'istanza del flusso di lavoro può essere ripresa. Si noti che la nuova definizione aggiornata e WorkflowIdentity deve essere usata.
Annotazioni
Per altre informazioni sull'uso di WorkflowApplication e WorkflowIdentity, vedere Uso di WorkflowIdentity e controllo delle versioni.
Nell'esempio seguente il MortgageWorkflow_v1.1.xaml flusso di lavoro dell'esempio precedente è stato compilato e viene caricato e ripreso usando la definizione aggiornata del flusso di lavoro.
// 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(...);