actualización dinámicaDynamic Update

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.Dynamic update provides a mechanism for workflow application developers to update the workflow definition of a persisted workflow instance. Puede ser para implementar una corrección de errores, nuevos requisitos o acomodar cambios inesperados.This can be to implement a bug fix, new requirements, or to accommodate unexpected changes. En este tema se proporciona información general de la funcionalidad de actualización dinámica presentada en .NET Framework 4.5.This topic provides an overview of the dynamic update functionality introduced in .NET Framework 4.5.

actualización dinámicaDynamic Update

Para aplicar actualizaciones dinámicas a una instancia de flujo de trabajo persistente, se crea una DynamicUpdateMap que contiene instrucciones para el runtime que describen cómo modificar la instancia de flujo de trabajo persistente para reflejar los cambios deseados.To apply dynamic updates to a persisted workflow instance, a DynamicUpdateMap is created that contains instructions for the runtime that describe how to modify the persisted workflow instance to reflect the desired changes. Una vez creada la asignación de actualización, se aplica a las instancias de flujo de trabajo persistentes deseadas.Once the update map is created, it is applied to the desired persisted workflow instances. Una vez que se aplica la actualización dinámica, la instancia de flujo de trabajo se puede reanudar mediante la nueva definición de flujo de trabajo actualizada.Once the dynamic update is applied, the workflow instance may be resumed using the new updated workflow definition. Hay cuatro pasos necesarios para crear y aplicar una asignación de actualización.There are four steps required to create and apply an update map.

  1. Prepare la definición de flujo de trabajo para la actualización dinámicaPrepare the workflow definition for dynamic update

  2. Actualice la definición de flujo de trabajo para reflejar los cambios deseadosUpdate the workflow definition to reflect the desired changes

  3. Crear la asignación de actualizaciónCreate the update map

  4. La asignación de actualización se aplican a las instancias de flujo de trabajo persistentes deseadasApply the update map to the desired persisted workflow instances

Nota

Observe que los pasos del 1 al 3, que tratan sobre la creación de la asignación de actualización, se pueden realizar independientemente de la aplicación de la actualización.Note that steps 1 through 3, which cover the creation of the update map, may be performed independently of applying the update. Un escenario común que el desarrollador del flujo de trabajo creará la asignación de actualización sin conexión y, a continuación, un administrador aplicará la actualización en un momento posterior.A common scenario that the workflow developer will create the update map offline, and then an administrator will apply the update at a later time.

Este tema proporciona información general sobre el proceso de actualización dinámica de agregar una nueva actividad a una instancia persistente de un flujo de trabajo compilado de XAML.This topic provides an overview of the dynamic update process of adding a new activity to a persisted instance of a compiled Xaml workflow.

Prepare la definición de flujo de trabajo para la actualización dinámicaPrepare the workflow definition for dynamic update

El primer paso del proceso de actualización dinámica es preparar la definición de flujo de trabajo deseada para la actualización.The first step in the dynamic update process is to prepare the desired workflow definition for update. Esto se hace mediante una llamada al método DynamicUpdateServices.PrepareForUpdate y el envío de la definición de flujo de trabajo para modificar.This is done by calling the DynamicUpdateServices.PrepareForUpdate method and passing in the workflow definition to modify. Este método valida y después recorre el árbol de flujo de trabajo para identificar todos los objetos como actividades y variables públicas que se deben etiquetar para que se puedan comparar más adelante con la definición de flujo de trabajo modificada.This method validates and then walks the workflow tree to identify all of the objects such as public activities and variables that need to be tagged so they can be compared later with the modified workflow definition. Cuando esto se completa, el árbol de flujo de trabajo se clona y se adjunta a la definición de flujo de trabajo original.When this is complete, the workflow tree is cloned and attached to the original workflow definition. Cuando se crea la asignación de la 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 se genera la asignación de actualización en función de las diferencias.When the update map is created, the updated version of the workflow definition is compared with the original workflow definition and the update map is generated based on the differences.

Para preparar un flujo de trabajo de XAML para la actualización dinámica se puede cargar en ActivityBuilder y, a continuación, ActivityBuilder se pasa a DynamicUpdateServices.PrepareForUpdate.To prepare a Xaml workflow for dynamic update it may be loaded into an ActivityBuilder, and then the ActivityBuilder is passed into DynamicUpdateServices.PrepareForUpdate.

Nota

Para obtener más información sobre cómo trabajar con flujos de trabajo serializados y ActivityBuilder, consulte serializar flujos de trabajo y actividades a y desde XAML.For more information about working with serialized workflows and ActivityBuilder, see Serializing Workflows and Activities to and from XAML.

En el ejemplo siguiente, se carga una definición de MortgageWorkflow (compuesta por una Sequence con varias actividades secundarias) en ActivityBuilder y, después, se prepara para la actualización dinámica.In the following example, a MortgageWorkflow definition (that consists of a Sequence with several child activities) is loaded into an ActivityBuilder, and then prepared for dynamic update. Después de que el método vuelva, ActivityBuilder contiene la definición de flujo de trabajo original junto con una copia.After the method returns, the ActivityBuilder contains the original workflow definition as well as a copy.

// 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);

Nota

Para descargar el código de ejemplo que acompaña a este tema, consulte código de ejemplo de actualización dinámica.To download the sample code that accompanies this topic, see Dynamic Update sample code.

Actualice la definición de flujo de trabajo para reflejar los cambios deseadosUpdate the workflow definition to reflect the desired changes

Una vez que la definición de flujo de trabajo se ha preparado para la actualización, pueden realizarse los cambios deseados.Once the workflow definition has been prepared for updating, the desired changes can be made. Puede agregar o quitar actividades, agregar, mover o eliminar variables públicas, agregar o quitar argumentos, y realizar cambios en la signatura de los delegados de actividad.You can add or remove activities, add, move or delete public variables, add or remove arguments, and make changes to the signature of activity delegates. No puede quitar una actividad en ejecución o cambiar la signatura de un delegado en ejecución.You cannot remove a running activity or change the signature of a running delegate. Estos cambios se pueden realizar mediante código o en un diseñador de flujo de trabajo rehospedado.These changes may be made using code, or in a re-hosted workflow designer. En el siguiente ejemplo, se agrega una actividad VerifyAppraisal personalizada a la secuencia que compone el cuerpo de MortgageWorkflow del ejemplo anterior.In the following example, a custom VerifyAppraisal activity is added to the Sequence that makes up the body of the MortgageWorkflow from the previous example.

// 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 la asignación de actualizaciónCreate the update map

Una vez que se ha modificado la definición de flujo de trabajo que se había preparado para la actualización, puede crearse la asignación de actualización.Once the workflow definition that was prepared for update has been modified, the update map can be created. Para crear una asignación de actualización dinámica, se invoca el método DynamicUpdateServices.CreateUpdateMap.To create a dynamic update map, the DynamicUpdateServices.CreateUpdateMap method is invoked. Devuelve un objeto DynamicUpdateMap que contiene la información que el runtime necesita para modificar una instancia de flujo de trabajo persistente de manera que se pueda cargar y reanudar con la nueva definición de flujo de trabajo.This returns a DynamicUpdateMap that contains the information the runtime needs to modify a persisted workflow instance so that it may be loaded and resumed with the new workflow definition. En el ejemplo siguiente, se crea una asignación dinámica para la definición modificada de MortgageWorkflow del ejemplo anterior.In the following example, a dynamic map is created for the modified MortgageWorkflow definition from the previous example.

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

Esta asignación de actualización se puede usar inmediatamente para modificar las instancias de flujo de trabajo persistentes o se puede guardar y aplicar actualizaciones más adelante, que es lo más frecuente.This update map can immediately be used to modify persisted workflow instances, or more typically it can be saved and the updates applied later. Una manera de guardar la asignación de actualización es serializarla en un archivo, como se muestra en el ejemplo siguiente.One way to save the update map is to serialize it to a file, as shown in the following example.

// 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 vuelve, 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 de forma que se pueda usar más adelante cuando se reanuden instancias de flujo de trabajo actualizadas.When DynamicUpdateServices.CreateUpdateMap returns, the cloned workflow definition and other dynamic update information that was added in the call to DynamicUpdateServices.PrepareForUpdate is removed, and the modified workflow definition is ready to be saved so that it can be used later when resuming updated workflow instances. En el ejemplo siguiente, la definición de flujo de trabajo modificada se guarda en MortgageWorkflow_v1.1.xaml.In the following example, the modified workflow definition is saved to 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();

La asignación de actualización se aplican a las instancias de flujo de trabajo persistentes deseadasApply the update map to the desired persisted workflow instances

La aplicación de la asignación de actualización se puede realizar en cualquier momento después de crearla.Applying the update map can be done at any time after creating it. Puede realizarse inmediatamente mediante la instancia de DynamicUpdateMap devuelta por DynamicUpdateServices.CreateUpdateMap o puede realizarse más adelante mediante una copia guardada de la asignación de actualización.It can be done right away using the DynamicUpdateMap instance that was returned by DynamicUpdateServices.CreateUpdateMap, or it can be done later using a saved copy of the update map. Para actualizar una instancia de flujo de trabajo, cárguela en WorkflowApplicationInstance mediante WorkflowApplication.GetInstance.To update a workflow instance, load it into a WorkflowApplicationInstance using WorkflowApplication.GetInstance. A continuación, cree una WorkflowApplication mediante la definición de flujo de trabajo actualizada y la WorkflowIdentity.Next, create a WorkflowApplication using the updated workflow definition, and the desired WorkflowIdentity. Esta WorkflowIdentity puede ser diferente de la que se usó para hacer persistente el flujo de trabajo original y normalmente es para reflejar que se ha modificado la instancia persistente.This WorkflowIdentity may be different than the one that was used to persist the original workflow, and typically is in order to reflect that the persisted instance has been modified. 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.Once the WorkflowApplication is created, it is loaded using the overload of WorkflowApplication.Load that takes a DynamicUpdateMap, and then unloaded with a call to WorkflowApplication.Unload. Aplica la actualización dinámica y hace persistente la instancia de flujo de trabajo actualizada.This applies the dynamic update and persists the updated workflow instance.

// 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();
}

Reanudar una instancia de flujo de trabajo actualizadaResuming an Updated Workflow Instance

Una vez aplicada la actualización dinámica, la instancia de flujo de trabajo puede reanudarse.Once dynamic update has been applied, the workflow instance may be resumed. Observe que deben usarse la nueva definición actualizada y WorkflowIdentity.Note that the new updated definition and WorkflowIdentity must be used.

Nota

Para obtener más información sobre cómo trabajar con WorkflowApplication y WorkflowIdentity, consulte utilizando WorkflowIdentity y el control de versiones.For more information about working with WorkflowApplication and WorkflowIdentity, see Using WorkflowIdentity and Versioning.

En el ejemplo siguiente, el flujo de trabajo de MortgageWorkflow_v1.1.xaml del ejemplo anterior se ha compilado, y se carga y se reanuda mediante la definición de flujo de trabajo actualizada.In the following example, the MortgageWorkflow_v1.1.xaml workflow from the previous example has been compiled, and is loaded and resumed using the updated workflow definition.

// 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(...);

Nota

Para descargar el código de ejemplo que acompaña a este tema, consulte código de ejemplo de actualización dinámica.To download the sample code that accompanies this topic, see Dynamic Update sample code.