Este artículo proviene de un motor de traducción automática.
Flujo de trabajo de ASP.NET
Web de aplicaciones que operaciones de ejecución larga soporte técnico
Michael Kennedy
Descarga de código de la Galería de código de MSDN
Examinar el código en línea
En este artículo se describen:
|
En este artículo se utilizan las siguientes tecnologías: Windows Workflow Foundation, ASP.NET |
Contenido
Controlar los flujos de trabajo
Actividades sincrónicas y asincrónicas
¿Qué exactamente entre por activo?
Realizar tareas sincrónicas asincrónica
Los flujos de trabajo y actividades
Persistencia
Hacer real
Integración con ASP.NET
UNA algunas cosas que Ponder
Muestre todos juntos
los desarrolladores de software a menudo se le pide que crear aplicaciones Web que admiten operaciones de larga ejecución. Un ejemplo es el proceso de desprotección de un almacén en línea, que puede tardar varios minutos en completarse. Mientras que es una operación de larga ejecución por algunos estándares, en este artículo examinará las operaciones de larga ejecución de una escala totalmente diferente: las operaciones que pueden tardar días, semanas o incluso meses para completarse. Un ejemplo de una operación de este tipo es el proceso de aplicación de empleo, que puede implicar las interacciones entre varias personas y el intercambio de muchos documentos reales.
En primer lugar, veamos un problema más benigno desde un punto de vista ASP.NET: tiene que diseñar una solución para una operación de desprotección en una tienda en línea. Existen consideraciones especiales para facilitar esta solución debido de su duración. Por ejemplo, se puede optar por almacenar los datos de carro de la compra en una sesión ASP.NET. Incluso puede optar por mover ese estado de sesión a una base de datos para permitir actualizaciones para el sitio y equilibrio de carga o servidor de estado fuera de proceso. Aun así, encontrará todas las herramientas que necesarias para solucionar este problema fácilmente son proporcionadas para por ASP.NET propio.
Sin embargo, cuando la duración de la operación aumenta más de la típica ASP.NET sesión duración (20 minutos) o requiere varios actores (como en mi ejemplo contratación), ASP.NET no ofrece compatibilidad con suficiente. Es posible que recuerde que los procesos de trabajo ASP.NET cerrar automáticamente de inactividad y reciclar periódicamente a sí mismos. Esto provocará problemas grandes para las operaciones de larga ejecución, como estado estuvo dentro de estos procesos se pierden.
Suponga por un momento que estaban en host estos muy larga ejecución operaciones dentro de un solo proceso. Claramente el proceso de trabajo de ASP.NET no es adecuado para ellos por los motivos descritos sólo para el. Por lo que quizá sería posible crear un servicio de windows se cuya única responsabilidad para poder ejecutar estas operaciones. Si nunca reiniciar este servicio, le se más cerca una solución que si mediante ASP.NET directamente, desde basta con tener un proceso de servicio que realiza no automáticamente reinicio, en teoría, garantiza que no se perderá el estado de la operación de larga ejecución.
¿Pero se esto realmente resuelve el problema?Probablemente no. ¿Qué ocurre si el servidor requiere equilibrio de carga?Que es muy difícil al que está vinculado a un único proceso. Peor, ¿qué ocurre si tiene que reiniciar el servidor o el proceso se bloquea?A continuación, todas las operaciones que se han ejecutando se perderán.
De hecho, cuando las operaciones de días o semanas para finalizar, necesita una solución que es independiente del ciclo de vida del proceso que se está ejecutando de. Esto en general es true, pero es especialmente importante para las aplicaciones Web ASP.NET.
Controlar los flujos de trabajo
Windows Workflow Foundation (WF) no es la tecnología que se trata de cuenta para la creación de aplicaciones Web. Sin embargo, hay varias claves características proporcionados por WF que hacen que una solución de flujo de trabajo merece la pena tener en cuenta. WF le ofrece la posibilidad de conseguir independencia del proceso para las operaciones de larga ejecución de flujos de trabajo inactivos descargar completamente desde el espacio de proceso y recarga automáticamente ellos en el proceso activo cuando ya no están inactivo (consulte la figura 1 ). Con WF, puede aumenta por encima del ciclo de vida no determinista del proceso de trabajo de ASP.NET y proporcionar para operaciones de larga ejecución dentro de la aplicación Web.
Figura 1 operaciones de mantener flujos de trabajo a través de las instancias de proceso
Dos características clave de WF se combinan para ofrecer esta capacidad. En primer lugar, asincrónicas actividades indicar al tiempo de ejecución del flujo de trabajo que el flujo de trabajo se inactivo mientras se espera en un evento externo. En segundo lugar, un servicio de persistencia se descargar inactivos flujos de trabajo del proceso de, guárdelo en una ubicación de almacenamiento duradero, como una base de datos y volver a cargar los flujos de trabajo cuando estén listas ejecutar de nuevo.
Esta independencia proceso tiene otras ventajas. Proporciona un medio sencillo de equilibrio de carga, así como durabilidad, tolerancia a cara de errores de proceso o servidor errores.
Actividades sincrónicas y asincrónicas
Las actividades son los elementos atómicos de WF. Todos los flujos de trabajo se crean de actividades en una trama para el modelo de diseño compuesto. De hecho, los flujos de trabajo propios son actividades simplemente especializadas. Estas actividades se pueden clasificar como sincrónica o asincrónica. Una actividad sincrónica ejecuta todas sus instrucciones desde el principio hasta el final.
Un ejemplo de una actividad sincrónica podría ser que calcula impuestos dado un pedido en una tienda en línea. Vamos a considerar acerca de cómo estos una actividad puede implementarse. Al igual que la mayoría de los actividades WF, la mayor parte del trabajo ocurre en el método Execute reemplazado. Los pasos de este método es posible que vaya algo como esto:
- Obtener los datos orden de una actividad anterior. Esto se consigue normalmente a través de enlace de datos, y verá un ejemplo de esto más adelante.
- Buscar el cliente asociado con el orden de una base de datos.
- Buscar la tasa de impuestos en una base de datos basado en ubicación del cliente.
- Hacer algunas matemático simple mediante la tasa de impuesto y los artículos de orden asociados con orden.
- Almacenar el impuesto total en una propiedad que pueden enlazar las actividades siguientes para completar el proceso de formalización.
- Señal para el tiempo de ejecución del flujo de trabajo que se ha completado esta actividad devolviendo el indicador de estado de finalización de los métodos Execute.
Es importante reconocer que no esperan. Siempre está trabajando. El método Execute sólo se ejecuta a través de los pasos y termina en resumen orden. Es la esencia de una actividad sincrónica: todo el trabajo se realiza en el método Execute.
Actividades asincrónicas son diferentes. A diferencia de sus homólogos sincrónicas, actividades asincrónicas ejecución para un período de tiempo y, a continuación, esperan un estímulo externo. Mientras se espera, las actividades esté inactivas. Cuando se produce el evento, en la actividad se reanuda la operación y se finaliza la ejecución.
Un ejemplo de una actividad asincrónica es un paso en el proceso de contratación, cuando una aplicación para una posición tiene que ser revisado por un administrador. Considere lo que puede suceder si este administrador se de vacaciones y no se obtendrá una oportunidad para revisar la aplicación hasta que la próxima semana. Es completamente poco razonable de bloqueo en el medio del método Execute mientras se espera para esta respuesta. Cuando el software de espera de una persona, es posible que tenga que esperar durante un largo periodo de tiempo. Tiene que considerar esto en el diseño.
¿Qué exactamente entre por activo?
En este momento semántica inglés y la semántica arquitectura difieren. Vamos a tomar un paso nuevo de WF y pensar de más general sobre lo que significa estar inactivo.
Considere la clase siguiente que usa un servicios Web para cambiar una contraseña:
public class PasswordOperation : Operation {
Status ChangePassword(Guid userId, string pw) {
// Create a web service proxy:
UserService svc = new UserService();
// This can take up to 20 sec for
// the web server to respond:
bool result = svc.ChangePassword( userId, pw );
Logger.AccountAction( "User {0} changed pw ({1}).",
userId, result);
return Status.Completed;
}
}
¿Es el método ChangePassword nunca inactivo?¿Si es así, donde?
El subproceso de este método está bloqueado esperando una respuesta HTTP del UserService. Conceptualmente por lo que la respuesta es sí, el subproceso está inactivo, espera la respuesta del servicio. ¿Pero puede el subproceso realmente hacer otro trabajo mientras está esperando en el servicio?No, no como que se utiliza actualmente. Por lo tanto, desde una perspectiva WF, este "flujo de trabajo" nunca es inactivo.
¿Por qué es nunca inactivo?Imagine que haya alguna clase programador mayor que ejecutar operaciones como ChangePassword eficazmente. Por eficazmente, me refiero ejecución varias operaciones en paralelo, utilizando el número mínimo de subprocesos necesarios para paralelismo completa y así sucesivamente. Resulta que la clave para esta eficacia es saber cuando se ejecuta la operación y cuando está inactivo. Dado que cuando una operación está inactiva, el programador puede utilizar el subproceso que se estaba ejecutando la operación para realizar otro trabajo hasta que se listo para ejecutar de nuevo la operación.
Por desgracia, el método ChangePassword es totalmente opaco que el programador. Debido a que aunque hay un período cuando está inactivo eficazmente, visto desde el exterior por el programador que método es una unidad única de bloqueo de trabajo. El programador no tiene ninguna capacidad de dividir aparte esa unidad de trabajo y volver a utilizar el subproceso durante el período de inactividad.
Realizar tareas sincrónicas asincrónica
Puede agregar esto necesario programar transparencia para el funcionamiento dividiendo la operación en dos partes: uno que ejecuta hacia arriba al punto donde la operación es potencialmente inactiva y otro que se ejecuta el código después del estado inactivo.
Para obtener el ejemplo hipotético mostrado anteriormente, puede utilizar las capacidades de asincrónicas proporcionadas por el proxy de servicio Web propio. Tenga en cuenta que es una simplificación y WF realmente funciona de forma un poco diferente, como verá en un minuto.
En la figura 2 , he creado una versión mejorada del método con cambiar contraseña denominado ChangePasswordImproved. Creo que el proxy de servicio Web como antes. A continuación, el método registra un método de devolución de llamada para recibir una notificación cuando el servidor ha respondido. A continuación, asincrónicamente ejecuta la llamada a servicio y notifique nuevo para el programador que la operación es inactivo, pero no finalizado, devolviendo Status.Executing. Este paso es importante, es este paso que permite que otro trabajo para llevarse a cabo por el programador mientras mi código de está inactivo. Por último, cuando se produce el evento completado, llamo el programador para indicar que la operación finalice y que puede mover en.
Llamada A servicio contraseña simple para cambiar de la figura 2
public class PasswordOperation : Operation {
Status ChangePasswordImproved(Guid userId, string pw) {
// Create a web service proxy:
UserService svc = new UserService();
svc.ChangePasswordComplete += svc_ChangeComplete;
svc.ChangePasswordAsync( userId, pw );
return Status.Executing;
}
void svc_ChangeComplete(object sender, PasswordArgs e) {
Logger.AccountAction( "User {0} changed pw ({1}).",
e.UserID, e.Result );
Scheduler.SignalCompleted( this );
}
}
Los flujos de trabajo y actividades
Ahora voy a aplicar el concepto de una operación está inactivo a la creación de actividades de WF. Esto es muy similar a lo que se ha visto anteriormente, pero ahora debe trabajar en el modelo WF.
WF incluye muchas actividades integradas. Sin embargo, cuando obtener comenzó crear sistemas reales con WF, rápidamente deseará empezar a crear sus propias actividades personalizadas reutilizables. Esto es fácil de hacer. Sólo definir una clase que deriva de la clase de actividad omnipresente. Éste es un ejemplo básico:
class MyActivity : Activity {
override ActivityExecutionStatus
Execute(ActivityExecutionContext ctx) {
// Do work here.
return ActivityExecutionStatus.Closed;
}
}
Para que la actividad que hacer nada útil, debe reemplazar el método Execute.Si va a crear una actividad sincrónica corta duración, a continuación, simplemente implementar operación de la actividad dentro de este método y devolverá el estado cerrado.
Hay unos problemas más grandes que es probable que tener en cuenta las actividades del mundo real. ¿Cómo se comunicará la actividad con otras actividades en el flujo de trabajo y la aplicación mayor que aloja el flujo de trabajo?¿Cómo se tener acceso a servicios como sistemas de base de datos, la interacción de interfaz de usuario y así sucesivamente?Para crear actividades sincrónicas, estos problemas son relativamente sencillo.
Creación de actividades asincrónicas, en otra parte, puede ser una tarea más compleja. Afortunadamente, el modelo de empleado se repite en las actividades más asincrónicas. De hecho, puede fácilmente capturar este patrón en una clase base, como mostraré en un momento.
Estos son los pasos básicos necesarios para crear más actividades asincrónicas:
- Crear una clase que deriva de la actividad.
- Reemplace el método Execute.
- Crear una cola de flujo de trabajo que puede utilizarse para recibir una notificación que ha completado la asincrónica de eventos que ha sido esperando.
- Suscribirse al evento de QueueItemAvailable de la cola.
- Iniciar el inicio de la operación de larga ejecución (por ejemplo, enviar un correo electrónico pidiendo un administrador para revisar una aplicación de una posición de trabajo).
- Espere a que un evento externo que se produzca. Esto indica que la actividad ha convertido en inactiva. Esto se indica a tiempo de ejecución del flujo de trabajo devolviendo ExecutionActivityStatus.Executing.
- Cuando se produce el evento, el método que controla el evento QueueItemAvailable quita el elemento de la cola, convierte al tipo datos esperados y procese los resultados.
- Normalmente esto termina la operación de la actividad. El tiempo de ejecución del flujo de trabajo está señalado, a continuación, devolviendo ActivityExecutionContext.CloseActivity.
Persistencia
Al principio de este artículo, dice que las dos cosas fundamentales que necesita para lograr la independencia de proceso a través de flujo de trabajo eran actividades asincrónicas y un servicio de persistencia. Ha visto la parte de las actividades asincrónicas. Ahora vamos a cavar en la tecnología que subyace a persistencia: servicios de flujo de trabajo.
Servicios de flujo de trabajo son un punto de extensibilidad de la clave para WF. El motor en tiempo de ejecución WF es una clase que crear una instancia en la aplicación para la ejecución del host flujos de trabajo. Esta clase tiene dos objetivos de diseño opuestos que simultáneamente se logra mediante el concepto de servicios de flujo de trabajo. El primer objetivo es para este flujo de trabajo en tiempo de ejecución ser un objeto ligero que puede utilizarse en muchos lugares. El segundo objetivo es para este tiempo de ejecución proporcionar capacidades eficaces para los flujos de trabajo mientras se está ejecutando. Por ejemplo, puede proporcionar la capacidad de conservar los flujos de trabajo inactivos, realizar un seguimiento del progreso del flujo de trabajo y admitir otras capacidades personalizados automáticamente.
El tiempo de ejecución del flujo de trabajo permanece ligera de forma predeterminada, ya que sólo un par de estas funciones se crean en. Opcionalmente, se instalan varios servicios de pesado como persistencia y seguimiento mediante el modelo de servicio. De hecho, la definición de un servicio es cualquier función global que desea proporcionar a los flujos de trabajo. Para instalar estos servicios en tiempo de ejecución, basta con llamar al método AddService sobre la clase WorkflowRuntime:
void AddService(object service)
Puesto AddService toma una referencia System.Object, puede agregar algo el flujo de trabajo que necesite.
Voy a trabajar con dos servicios. En primer lugar, VOY a utilizar WorkflowQueuingService para tener acceso a las colas de flujo de trabajo que son fundamentales para crear actividades asincrónicas. Este servicio se instala de forma predeterminada y no se pueden personalizar. El otro servicio es SqlWorkflowPersistenceService. Este servicio, por supuesto, proporcionará las funciones de persistencia y no se instala de forma predeterminada. Afortunadamente, se incluye con WF. Sólo tendrá que agregar, al tiempo de ejecución.
Con un nombre como SqlWorkflowPersistenceService, seguro que una base de datos será necesario en alguna parte. Puede crear una base de datos vacía para este propósito o puede agregar algunas tablas a una base de datos existente. Personalmente prefiero usar una base de datos dedicada en lugar de mingle datos de persistencia de flujo de trabajo con los otros datos. Por lo que crea una base de datos vacía en SQL Server denominada WF_Persist. Creo el esquema de base de datos necesarios y los procedimientos almacenados mediante la ejecución de un par de secuencias de comandos. Estos se instalan como parte de Microsoft .NET Framework y están de forma predeterminada ubicada en esta carpeta:
C:\Windows\Microsoft.NET\Framework\v3.0\Windows Foundation\SQL\EN\ de flujo de trabajo
Se desea ejecute la secuencia de comandos SqlPersistenceService_Schema.sql primero y a continuación, ejecute la secuencia de comandos SqlPersistenceService_Logic.sql. Ahora PUEDO usar esta base de datos para la persistencia si se pasa la cadena de conexión al servicio de persistencia:
SqlWorkflowPersistenceService sqlSvc =
new SqlWorkflowPersistenceService(
@"server=.;database=WF_Persist;trusted_connection=true",
true, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
wfRuntime.AddService(sqlSvc);
Esta llamada de método simple de AddService es todo lo que se necesita para empezar a descargar flujos de trabajo inactivos y almacena en la base de datos y, a continuación, restaurarlos cuando es necesario volver a.El motor en tiempo de ejecución WF se encarga de todo lo demás.
Hacer real
Ahora que tiene suficiente de los apuntalamientos técnicos en su lugar, tejido conjuntamente para crear un sitio Web de ASP.NET que admita operaciones de larga ejecución. Los tres elementos principales que se ven en este ejemplo son la construcción de actividades asincrónicas, integrar el tiempo de ejecución del flujo de trabajo en la aplicación Web y comunicarse con el flujo de trabajo de las páginas Web.
Voy a estar trabajando con una compañía de consultoría de .NET hipotética llamada Trey Research. Le gustaría automatizar el proceso recruiting y contratación para sus consultores. Así se esté creando un sitio Web de ASP.NET para admitir este proceso de contratación. Me va a mantener las cosas muy sencillo, pero hay varios pasos para el proceso:
- Un candidato de trabajo visitan el sitio Web de Trey Research y el interés express en un trabajo.
- Se enviará un mensaje de correo electrónico al administrador de destacar que hay un nuevo candidato.
- Este Administrador se revise la aplicación y apruebe el candidato para una posición concreta.
- Un mensaje de correo electrónico se enviará el candidato con información sobre la posición propuesta.
- El solicitante visite el sitio Web y uno Aceptar o rechazar la posición.
Aunque este proceso es sencillo, hay varios pasos donde la aplicación está esperando una persona devolver y rellenar más información. Estos puntos inactivos pueden tardar unos minutos. Por lo que son perfectas para demostrar un proceso de larga ejecución.
Esta aplicación Web se incluye en el código fuente para el artículo. Sin embargo, para ver el efecto completo deberá crear la base de datos de persistencia y configurar el ejemplo para utilizarlo. Ha creado un modificador para administrar si el servicio de persistencia está en o desactivado y estableció que esté fuera de forma predeterminada. Para activarla, establezca usePersistDB en true en la sección AppSettings de web.config. Si desea ver en ejecución mientras leen, puede ver elVisor de trabajo asincrónicoejecutar en mi sitio Web.
La figura 3 el proceso de contratación como un flujo de trabajo
Comenzará a diseñar el flujo de trabajo completamente independiente de ASP.NET. Para crear el flujo de trabajo, VOY a crear cuatro actividades personalizadas. La primera es una actividad de correo electrónico de envío y será una simple actividad sincrónica. Los otros tres representan los pasos 1, 3 y 5 mostrada anteriormente y serán actividades asincrónicas. Estas actividades son clave para el éxito de la operación de larga ejecución. Llamará estos GatherEmployeeInfoActivity, AssignJobActivity y ConfirmJobActivity, respectivamente. A continuación, combinarán estas actividades en el flujo de trabajo hay que reconocer que la configuración básica que se muestra en la figura 3 .
La actividad de correo electrónico de envío es sencilla para que no entran en los detalles de esa actividad en este artículo. Es una actividad sincrónica al igual que la clase MyActivity mostrada anteriormente. Eche un vistazo a la descarga de código para obtener más información.
Me que deja con la creación de las tres actividades asincrónicas. Guardará yo mismo mucho trabajo si puede encapsular ese proceso de ocho paso para crear una actividad asincrónica en una clase base común. Con ese fin, se define una clase denominada AsyncActivity (consulte la figura 4 ). Tenga en cuenta que esta lista no incluye varios métodos auxiliar interna o tratamiento de errores está presente en el código real. Los detalles de la que se izquierda salida por motivos de brevedad.
La figura 4 AsyncActivity
public abstract class AsyncActivity : Activity {
private string queueName;
protected AsyncActivity(string queueName) {
this.queueName = queueName;
}
protected WorkflowQueue GetQueue(
ActivityExecutionContext ctx) {
var svc = ctx.GetService<WorkflowQueuingService>();
if (!svc.Exists(queueName))
return svc.CreateWorkflowQueue(queueName, false);
return svc.GetWorkflowQueue(queueName);
}
protected void SubscribeToItemAvailable(
ActivityExecutionContext ctx) {
GetQueue(ctx).QueueItemAvailable += queueItemAvailable;
}
private void queueItemAvailable(
object sender, QueueEventArgs e) {
ActivityExecutionContext ctx =
(ActivityExecutionContext)sender;
try { OnQueueItemAvailable(ctx); }
finally { ctx.CloseActivity(); }
}
protected abstract void OnQueueItemAvailable(
ActivityExecutionContext ctx);
}
En esta clase base, podrá ver que ajusta hasta varias de las partes tediosas y repetitivas de crear una actividad asincrónica.Vamos a ejecutar a través de esta clase desde arriba a abajo. Empezando por el constructor, pase una cadena para el nombre de la cola. Las colas de flujo de trabajo son los puntos de entrada para la aplicación de host (las páginas Web) para pasar datos de las actividades mientras restante imprecisa. Estas colas se conocen por instancia de flujo de trabajo y el nombre, por lo que cada actividad asincrónica es necesario su nombre de cola distintos.
Luego, defina el método GetQueue. Como puede ver, acceso y crear colas de flujo de trabajo es sencillo, pero algo tedioso. Crea este método como un método auxiliar para su uso dentro de esta clase y sus clases derivadas.
A continuación, definir un método denominado SubscribeToItemAvailable. Este método encapsula los detalles de suscribiéndose al evento que desencadena cuando llegue un elemento a la cola de flujo de trabajo. Esto casi siempre representa la finalización de una larga espera período en el flujo de trabajo ha estado inactivo. Por lo que el caso de uso pasa algo como esto:
- Comenzar la operación de larga y llamar a SubscribeToItemAvailable.
- Indique el tiempo de ejecución del flujo de trabajo que la actividad es inactiva.
- La instancia de flujo de trabajo se serializa en la base de datos por el servicio de persistencia.
- Cuando finaliza la operación, un elemento se envía a la cola de flujo de trabajo.
- Esto desencadena la instancia de flujo de trabajo que restaurarse desde la base de datos.
- El método abstracto plantilla OnQueueItemAvailable se ejecuta por la AsyncActivity base.
- La actividad finaliza la operación.
Para ver esta clase AsyncActivity en acción, vamos a implementan la clase de AssignJobActivity. Las otras actividades dos asincrónicas son similares y se incluyen en la descarga de código.
En la figura 5 , puede ver cómo AssignJobActivity utiliza la plantilla proporcionada por la clase base AsyncActivity. Reemplace ejecución para realizar cualquier trabajo preliminar para comenzar la actividad de larga ejecución, aunque en este caso no existe realmente no cualquiera. A continuación, suscribir al evento cuando hay más datos disponibles.
La figura 5 AssignJobActivity
public partial class AssignJobActivity : AsyncActivity {
public const string QUEUE NAME = "AssignJobQueue";
public AssignJobActivity()
: base(QUEUE_NAME)
{
InitializeComponent();
}
protected override ActivityExecutionStatus Execute(
ActivityExecutionContext ctx) {
// Runs before idle period:
SubscribeToItemAvailable(ctx);
return ActivityExecutionStatus.Executing;
}
protected override void OnQueueItemAvailable(
ActivityExecutionContext ctx) {
// Runs after idle period:
Job job = (Job)GetQueue(ctx).Dequeue();
// Assign job to employee, save in DB.
Employee employee = Database.FindEmployee(this.WorkflowInstanceId);
employee.Job = job.JobTitle;
employee.Salary = job.Salary;
}
}
Hay un implícito contrato aquí que la aplicación host, la página Web, enviará un nuevo objeto de trabajo en cola de la actividad cuando ha recopilado esa información desde el administrador. Esto indica la actividad que se encuentra ACEPTAR para continuar. Se actualizará el empleado en la base de datos. La siguiente actividad en el flujo de trabajo enviará un mensaje de correo electrónico a los empleados potenciales que se le informa que este trabajo se propone para su posición.
Integración con ASP.NET
Eso es cómo funciona dentro del flujo de trabajo. ¿Pero hace cómo se inicia el flujo de trabajo?¿Cómo la página Web en realidad recopilar la oferta de trabajo desde el administrador?¿Cómo pasa el trabajo a la actividad?
Primeras cosas primero: echemos un vistazo a cómo iniciar el flujo de trabajo. En la página de destino para el sitio Web hay un vínculo aplicar ahora. Cuando el solicitante hace clic en este vínculo, se inicia el flujo de trabajo y la navegación a través de la interfaz de usuario en paralelo:
protected void LinkButtonJoin_Click(
object sender, EventArgs e) {
WorkflowInstance wfInst =
Global.WorkflowRuntime.CreateWorkflow(typeof(MainWorkflow));
wfInst.Start();
Response.Redirect(
"GatherEmployeeData.aspx?id=" + wfInst.InstanceId);
}
Simplemente llame al CreateWorkflow en tiempo de ejecución del flujo de trabajo y inicie la instancia de flujo de trabajo. Después de eso realice un seguimiento de la instancia de flujo de trabajo pasando el IDENTIFICADOR de instancia a todas las páginas Web siguientes base de datos como un parámetro de consulta.
¿Cómo envía datos de la página Web en el flujo de trabajo?Echemos un vistazo a la página trabajo asignado, en la figura 6 , donde un administrador elige un trabajo para un candidato.
Figura 6 Asignación de un trabajo
public class AssignJobPage : System.Web.UI.Page {
/* Some details omitted */
void ButtonSubmit_Click(object sender, EventArgs e) {
Guid id = QueryStringData.GetWorkflowId();
WorkflowInstance wfInst = Global.WorkflowRuntime.GetWorkflow(id);
Job job = new Job();
job.JobTitle = DropDownListJob.SelectedValue;
job.Salary = Convert.ToDouble(TextBoxSalary.Text);
wfInst.EnqueueItem(AssignJobActivity.QUEUE_NAME, job, null, null);
buttonSubmit.Enabled = false;
LabelMessage.Text = "Email sent to new recruit.";
}
}
La página Web de trabajo de asignación es en gran medida sólo un formulario de entrada sencillo. Tiene una lista desplegable de trabajos disponibles y un cuadro de texto para el salario propuesto. También muestra el solicitante actual, aunque ese código se omite en la lista. Cuando el administrador asigna una posición y Salario al solicitante, se haga clic en el botón de envío y ejecute el código en la figura 6 .
Esta página usa el IDENTIFICADOR de instancia de flujo de trabajo como un parámetro de cadena de consulta para buscar la instancia de flujo de trabajo asociado. A continuación, un objeto de trabajo se crea y se inicializa con los valores del formulario. Por último, enviar esta información en la actividad por enqueuing el trabajo en cola de esa actividad. Éste es el paso clave que vuelve a cargar el flujo de trabajo inactivo y permite que continúe la ejecución. AssignJobActivity se asociar este trabajo al empleado previamente recopilado y guardarlas en una base de datos.
Estas listas código dos últimos haga hincapié en cómo fundamental flujo de trabajo las colas son para el éxito de actividades asincrónicas y comunicación de flujo de trabajo con el host externo. También es importante tener en cuenta que el uso de flujo de trabajo no tiene aquí ningún impacto del flujo de página. Aunque WF también puede utilizar para controlar el flujo de página, es simplemente no el objetivo de este artículo.
EnFigura 6, hemos visto que tiene acceso a tiempo de ejecución del flujo de trabajo a través de la clase de aplicación global, los siguientes:
WorkflowInstance wfInst =
Global.WorkflowRuntime.GetWorkflow(id);
Esto me lleva al punto final de la integración de flujo de trabajo de Windows en nuestra aplicación Web: todos los flujos de trabajo se ejecución en el tiempo de ejecución del flujo de trabajo. Aunque puede haber tantos runtimes de flujo de trabajo como desee en la AppDomain, más a menudo sentido tener un tiempo de ejecución de flujo de trabajo única. A causa de ello, y porque el objeto de tiempo de ejecución WF está es seguro para la ejecución de subprocesos, realiza, una propiedad estática pública de la clase de aplicación global. Además, iniciar el tiempo de ejecución del flujo de trabajo en el evento de inicio de aplicación y detener, en el evento de detención de aplicación. la figura 7 es una versión abreviada de la clase de aplicación global.
La figura 7 iniciar el en tiempo de ejecución flujo de trabajo
public class Global : HttpApplication {
public static WorkflowRuntime WorkflowRuntime { get; set; }
protected void Application_Start(object sender, EventArgs e) {
WorkflowRuntime = new WorkflowRuntime();
InstallPersistenceService();
WorkflowRuntime.StartRuntime();
// ...
}
protected void Application_End(object sender, EventArgs e) {
WorkflowRuntime.StopRuntime();
WorkflowRuntime.Dispose();
}
void InstallPersistenceService() {
// Code from listing 4.
}
}
En el evento de inicio aplicación, crear el motor en tiempo de ejecución, instalar el servicio de persistencia y, iniciar el motor en tiempo de ejecución. Y en el evento final de la aplicación, detendrá el tiempo de ejecución. Éste es un paso importante. Bloqueará si se están ejecutando los flujos de trabajo hasta que se han descargado estos flujos de trabajo. Después de detener el tiempo de ejecución, LLAMO a Dispose. Aunque la llamada a StopRuntime y, a continuación, a Dispose puede parecer redundante, no es. Tiene que llamar a ambos métodos en ese orden.
UNA algunas cosas que Ponder
Permítanme proporcionarle algunas cosas que pensar que directamente no tocar, presenta en formato de pregunta y respuesta. ¿Por qué no utilizar ManualWorkflowSchedulerService?A menudo cuando las personas hablar sobre integración de WF con ASP.NET haga hincapié en que se debe reemplazar el programador de flujos de trabajo predeterminado (que utiliza el grupo de subprocesos) con un servicio denominado ManualWorkflowSchedulerService. La razón es porque no es necesario o realmente adecuado para nuestros objetivos de larga ejecución. El programador manual es bueno cuando espera que ejecutar un flujo de trabajo única para finalizar dentro de una determinada solicitud. Tiene sentido menos cuando se ejecuta el flujo de trabajo a través de duración de proceso, no para mencionar en las solicitudes.
¿Hay una forma de realizar el seguimiento del progreso actual de una instancia de flujo de trabajo determinado?Sí, no existe servicio integrado en WF de seguimiento una completa se y se utiliza de forma similar como el servicio de persistencia de SQL. Ver la columna de fundamentos de marzo de 2007 "Seguimiento de servicios en Windows Workflow Foundation"por Matt Milner.
Muestre todos juntos
Pueden resumir las técnicas tratadas en este artículo con un par de pasos. Inició mediante esquemas de por qué los procesos de trabajo ASP.NET y el modelo de proceso en general no son adecuados para muy larga ejecución operaciones. Para anular esta limitación aprovechó dos características que se combinan para lograr la independencia del proceso de WF: actividades asincrónicas y persistencia de flujo de trabajo.
Dado que creación de actividades asincrónicas puede ser un poco complicado, encapsulan los detalles en la clase base de AsyncActivity introducida en este artículo. A continuación, expresa la operación de larga ejecución, como un flujo de trabajo secuencial creado con actividades asincrónicas que puede incorporar una aplicación Web y obtener independencia de procesos de forma gratuita.
Por último, demostró que integrar el flujo de trabajo en ASP.NET tiene dos partes básicas: comunicación con las actividades a través de una cola de flujo de trabajo y alojamiento el tiempo de ejecución de la clase de aplicación global.
Ahora que ha visto integrado con ASP.NET para admitir las operaciones de larga ejecución de WF, tiene una herramienta más eficaz para crear soluciones en la parte superior de .NET Framework.
Michael Kennedy es un instructor de DevelopMentor especializada en tecnologías de .NET principales así como ágil y TDD las metodologías de desarrollo. Seguir el ritmo Michael a través de su sitio Web y el blog enmichaelckennedy. NET.