Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La actualización dinámica proporciona un mecanismo para que los desarrolladores de aplicaciones de flujo de trabajo actualicen la definición de flujo de trabajo de una instancia de flujo de trabajo persistente. Esto puede ser implementar una corrección de errores, nuevos requisitos o para dar cabida a cambios inesperados. En este tema se proporciona información general sobre la funcionalidad de actualización dinámica introducida en .NET Framework 4.5.
Para aplicar actualizaciones dinámicas a una instancia de flujo de trabajo persistente, se crea un DynamicUpdateMap objeto que contiene instrucciones para el tiempo de ejecución que describe cómo modificar la instancia de flujo de trabajo persistente para reflejar los cambios deseados. Una vez creado el mapa de actualización, se aplica a las instancias de flujo de trabajo persistentes deseadas. Una vez aplicada la actualización dinámica, la instancia de flujo de trabajo se puede reanudar mediante la nueva definición de flujo de trabajo actualizada. Hay cuatro pasos necesarios para crear y aplicar un mapa de actualizaciones.
- Prepare la definición del flujo de trabajo para la actualización dinámica.
- Actualice la definición del flujo de trabajo para reflejar los cambios deseados.
- Cree el mapa de actualización.
- Aplique el mapa de actualizaciones a las instancias persistentes de flujo de trabajo deseadas.
Nota:
Los pasos del 1 al 3, que abarcan la creación del mapa de actualización, se pueden realizar independientemente de aplicar la actualización. Un escenario común es que el desarrollador de flujos de trabajo creará el mapa de actualización sin conexión y, a continuación, un administrador aplicará la actualización en un momento posterior.
En este artículo se proporciona información general sobre el proceso de actualización dinámica para agregar una nueva actividad a una instancia persistente de un flujo de trabajo xaml compilado.
Preparación de la definición del flujo de trabajo para la actualización dinámica
El primer paso del proceso de actualización dinámica es preparar la definición de flujo de trabajo deseada para la actualización. Para ello, se llama al DynamicUpdateServices.PrepareForUpdate método y pasa la definición de flujo de trabajo que se va a modificar. Este método valida y, a continuación, recorre el árbol de flujo de trabajo para identificar todos los objetos, como actividades públicas y variables que deben etiquetarse para que se puedan comparar más adelante con la definición de flujo de trabajo modificada. Una vez completado, el árbol de flujo de trabajo se clona y se adjunta a la definición de flujo de trabajo original. Cuando se crea la asignación de actualización, la versión actualizada de la definición de flujo de trabajo se compara con la definición de flujo de trabajo original y la asignación de actualización se genera en función de las diferencias.
Para preparar un flujo de trabajo Xaml para una actualización dinámica, se puede cargar en un ActivityBuilder y luego pasar el ActivityBuilder al DynamicUpdateServices.PrepareForUpdate.
Nota:
Para obtener más información sobre cómo trabajar con flujos de trabajo serializados y ActivityBuilder, consulta Serializar flujos de trabajo y actividades hacia y desde XAML.
En el ejemplo siguiente, se carga una MortgageWorkflow
definición (que consta de una Sequence con varias actividades secundarias) en ActivityBuildery, a continuación, se prepara para la actualización dinámica. Una vez devuelto el método , ActivityBuilder contiene la definición de flujo de trabajo original, así como 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);
Actualizar la definición del flujo de trabajo para reflejar los cambios deseados
Una vez preparada la definición del flujo de trabajo para la actualización, se pueden realizar los cambios deseados. Puede agregar o quitar actividades, agregar, mover o eliminar variables públicas, agregar o quitar argumentos y realizar cambios en la firma de los delegados de actividad. No se puede quitar una actividad en ejecución ni cambiar la firma de un delegado en ejecución. Estos cambios se pueden realizar mediante código o en un diseñador de flujo de trabajo rehospedado. En el siguiente ejemplo, se agrega una actividad VerifyAppraisal
personalizada a la secuencia que compone el cuerpo de MortgageWorkflow
del ejemplo anterior.
// 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);
Crear el mapa de actualización
Una vez modificada la definición de flujo de trabajo preparada para la actualización, se puede crear el mapa de actualización. Para crear un mapa de actualización dinámica, se invoca el método DynamicUpdateServices.CreateUpdateMap. Esto devuelve un DynamicUpdateMap que contiene la información que necesita el tiempo de ejecución para modificar una instancia de flujo de trabajo persistente, de modo que se pueda cargar y reanudar con la nueva definición de flujo de trabajo. En el ejemplo siguiente, se crea un mapa dinámico para la definición modificada MortgageWorkflow
del ejemplo anterior.
// Create the update map.
DynamicUpdateMap map = DynamicUpdateServices.CreateUpdateMap(ab);
Este mapa de actualizaciones se puede usar inmediatamente para modificar instancias de flujo de trabajo persistentes o, más comúnmente, se puede guardar para aplicar las actualizaciones más adelante. Una manera de guardar el mapa de actualización es serializarlo en un archivo, como se muestra en el ejemplo siguiente.
// 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);
}
Cuando DynamicUpdateServices.CreateUpdateMap se devuelve, se quita la definición de flujo de trabajo clonada y otra información de actualización dinámica que se agregó en la llamada a DynamicUpdateServices.PrepareForUpdate y la definición de flujo de trabajo modificada está lista para guardarse para que se pueda usar más adelante al reanudar las instancias de flujo de trabajo actualizadas. En el ejemplo siguiente, la definición de flujo de trabajo modificada se guarda en 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();
Aplicar el mapa de actualización a las instancias de flujo de trabajo persistentes deseadas
La aplicación del mapa de actualización se puede realizar en cualquier momento después de crearlo. Se puede hacer inmediatamente mediante la DynamicUpdateMap instancia devuelta por DynamicUpdateServices.CreateUpdateMap, o también se puede hacer más adelante mediante una copia guardada del mapa de actualizaciones. Para actualizar una instancia de flujo de trabajo, cárguela en un WorkflowApplicationInstance utilizando WorkflowApplication.GetInstance. A continuación, cree una WorkflowApplication mediante la definición de flujo de trabajo actualizada y la WorkflowIdentity. Esto WorkflowIdentity puede ser diferente del que se usó para conservar el flujo de trabajo original y normalmente es para reflejar que se ha modificado la instancia persistente. Una vez que se crea WorkflowApplication, se carga mediante la sobrecarga de WorkflowApplication.Load que toma DynamicUpdateMap y después se descarga con una llamada a WorkflowApplication.Unload. Esto aplica la actualización dinámica y conserva la instancia de flujo de trabajo actualizada.
// 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();
}
Reanudación de una instancia de flujo de trabajo actualizada
Una vez aplicada la actualización dinámica, se puede reanudar la instancia de flujo de trabajo. Tenga en cuenta que la nueva definición actualizada y WorkflowIdentity deben usarse.
Nota:
Para obtener más información sobre cómo trabajar con WorkflowApplication y WorkflowIdentity, vea Uso de WorkflowIdentity y Control de versiones.
En el ejemplo siguiente, se ha compilado el MortgageWorkflow_v1.1.xaml
flujo de trabajo del ejemplo anterior y se carga y se reanuda mediante la definición de flujo de trabajo actualizada.
// 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(...);