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.
Este tema es aplicable a Windows Workflow Foundation 4.
Una definición de flujo de trabajo es un árbol de objetos de actividad configurados. Este árbol de actividades se puede definir de muchas maneras, incluido XAML editado a mano o el uso del Diseñador de flujo de trabajo para generar XAML. El uso de XAML, sin embargo, no es un requisito. También se pueden crear definiciones de flujo de trabajo mediante programación. En este tema se proporciona información general sobre cómo crear definiciones de flujo de trabajo mediante código.
Crear definiciones de flujo de trabajo
Se puede crear una definición de flujo de trabajo creando instancias de un tipo de actividad y configurando las propiedades del objeto de la actividad. En el caso de actividades que no contengan actividades secundarias, puede llevarse a cabo con algunas líneas de código.
Activity wf = new WriteLine
{
Text = "Hello World."
};
WorkflowInvoker.Invoke(wf);
![]() |
---|
Los ejemplos de este tema usan WorkflowInvoker para ejecutar los flujos de trabajo de ejemplo. Para obtener más información sobre invocar flujos de trabajo, pasar argumentos y las distintas opciones de hospedaje que están disponibles, vea Usar WorkflowInvoker y WorkflowApplication. |
En este ejemplo se crea un flujo de trabajo que consta de una única actividad WriteLine. Se establece el argumento Text de la actividad WriteLine y se invoca el flujo de trabajo. Si una actividad contiene actividades secundarias, el método de construcción es similar. En el siguiente ejemplo se usa una actividad Sequence que contiene dos actividades WriteLine.
Activity wf = new Sequence
{
Activities =
{
new WriteLine
{
Text = "Hello"
},
new WriteLine
{
Text = "World."
}
}
};
WorkflowInvoker.Invoke(wf);
Usar inicializadores de objeto
Los ejemplos en esta tema usan la sintaxis de inicialización del objeto. Esta sintaxis puede ser una forma útil de crear definiciones de flujo de trabajo en el código porque proporciona una vista jerárquica de las actividades en el flujo de trabajo y muestra la relación entre las actividades. No hay ningún requisito para usar la sintaxis de inicialización de objeto al crear los flujos de trabajo mediante programación. El ejemplo siguiente es equivalente en su funcionamiento al ejemplo anterior.
WriteLine hello = new WriteLine();
hello.Text = "Hello";
WriteLine world = new WriteLine();
world.Text = "World";
Sequence wf = new Sequence();
wf.Activities.Add(hello);
wf.Activities.Add(world);
WorkflowInvoker.Invoke(wf);
Para obtener más información sobre los inicializadores de objeto, vea Cómo: Inicializar objetos sin llamar a un constructor (Guía de programación de C#) y Cómo: Declarar un objeto usando un inicializador de objeto.
Trabajar con variables, valores literales y expresiones
Al crear una definición de flujo de trabajo mediante código, tenga en cuenta qué código se ejecuta como parte de la creación de la definición de flujo de trabajo y qué código se ejecuta como parte de la ejecución de una instancia de ese flujo de trabajo. Por ejemplo, el siguiente flujo de trabajo está pensado para generar un número aleatorio y escribirlo en la consola.
Variable<int> n = new Variable<int>
{
Name = "n"
};
Activity wf = new Sequence
{
Variables = { n },
Activities =
{
new Assign<int>
{
To = n,
Value = new Random().Next(1, 101)
},
new WriteLine
{
Text = new InArgument<string>((env) => "The number is " + n.Get(env))
}
}
};
Cuando se ejecuta este código de definición de flujo de trabajo, se realiza la llamada a Random.Next
y el resultado se almacena en la definición de flujo de trabajo como un valor literal. Se pueden invocar muchas instancias de este flujo de trabajo y todas mostrarían el mismo número. Para que la generación de números aleatorios se produzcan durante la ejecución del flujo de trabajo, se debe usar una expresión que se evalúa con caja ejecución del flujo de trabajo.
new Assign<int>
{
To = n,
Value = new VisualBasicValue<int>("New Random().Next(1, 101)")
}
VisualBasicValue representa una expresión en sintaxis de Visual Basic que se puede usar como un valor de r en una expresión y se puede evaluar cada vez que se ejecuta la actividad contenedora. El resultado de la expresión se asigna a la variable de flujo de trabajo n
. La actividad siguiente usa estos resultados en el flujo de trabajo. Para tener acceso al valor de la variable de flujo de trabajo ActivityContext en el tiempo de ejecución, se necesita n
. Se puede tener acceso a esto con la siguiente expresión lambda.
new WriteLine
{
Text = new InArgument<string>((env) => "The number is " + n.Get(env))
}
Las expresiones lambda no son serializables para el formato XAML. Para que esta expresión sea compatible con XAML, use ExpressionServices y Convert, tal y como se muestra en el ejemplo siguiente.
new WriteLine
{
//Text = new InArgument<string>((env) => "The number is " + n.Get(env))
Text = ExpressionServices.Convert((env) => "The number is " + n.Get(env))
}
También se puede utilizar VisualBasicValue.
new WriteLine
{
//Text = new InArgument<string>((env) => "The number is " + n.Get(env))
//Text = ExpressionServices.Convert((env) => "The number is " + n.Get(env))
Text = new VisualBasicValue<string>("\"The number is \" + n.ToString()")
}
Para obtener más información sobre expresiones, vea Expresiones.
Argumentos y actividades dinámicas
Una definición de flujo de trabajo se crea en código ensamblando las actividades en un árbol de actividad y configurando propiedades y argumentos. Se pueden enlazar los argumentos existentes, aunque los nuevos no pueden agregarse a las actividades. Esto incluye argumentos de flujo de trabajo pasados a la actividad raíz. En código imperativo, los argumentos de flujo de trabajo se especifican como propiedades en un nuevo tipo CLR. En XAML se declaran usando x:Class y x:Member. Dado que no se ha creado ningún nuevo tipo de CLR cuando una definición de flujo de trabajo se crea como un árbol de objetos en memoria, no se pueden agregar argumentos. Sin embargo, los argumentos se pueden agregar a DynamicActivity. En este ejemplo, se crea un DynamicActivity que toma dos argumentos enteros y los agrega juntos y devuelve el resultado. DynamicActivityProperty se crea para cada argumento y el resultado de la operación se asigna al argumento Result de DynamicActivity.
InArgument<int> Operand1 = new InArgument<int>();
InArgument<int> Operand2 = new InArgument<int>();
DynamicActivity<int> wf = new DynamicActivity<int>
{
Properties =
{
new DynamicActivityProperty
{
Name = "Operand1",
Type = typeof(InArgument<int>),
Value = Operand1
},
new DynamicActivityProperty
{
Name = "Operand2",
Type = typeof(InArgument<int>),
Value = Operand2
}
},
Implementation = () => new Sequence
{
Activities =
{
new Assign<int>
{
To = new ArgumentReference<int> { ArgumentName = "Result" },
Value = new InArgument<int>((env) => Operand1.Get(env) + Operand2.Get(env))
}
}
}
};
Dictionary<string, object> wfParams = new Dictionary<string, object>
{
{ "Operand1", 25 },
{ "Operand2", 15 }
};
int result = WorkflowInvoker.Invoke(wf, wfParams);
Console.WriteLine(result);
Para obtener más información sobre actividades dinámicas, vea Crear una actividad en el tiempo de ejecución con DynamicActivity.