Cet article a fait l'objet d'une traduction automatique.
Flux de travail ASP.NET
Web les applications qui opérations en cours d'exécution-longue prise en charge
Michael Kennedy
Téléchargement de code disponible de la bibliothèque de code MSDN
Parcourir le code en ligne
Cet article présente :
|
Cet article utilise les technologies suivantes : Windows Workflow Foundation, ASP.NET |
Contenu
Harnessing flux de travail
Activités synchrones et asynchrones
Les exactement vous moyennes par inactif ?
Effectuer les tâches synchrones asynchrone
Flux de travail et activités
Persistance
Rendre son réel
Intégration avec ASP.NET
A choses à réfléchir
Il collecte tous ensemble
les développeurs de logiciels êtes souvent invités à créer des applications Web qui prennent en charge les opérations de longue. Un exemple est le processus extraction d'un magasin en ligne, qui peut prendre plusieurs minutes. Qui est une opération de longue par certaines normes, dans cet article J'AI explorerons durables opérations d'une échelle totalement différente : opérations qui peuvent prendre les jours, semaines, ou même mois. Un exemple de cette opération est le processus application d'emploi, qui peut impliquer les interactions entre plusieurs personnes et l'échange de nombreux documents réels.
Tout d'abord, étudions un problème plus bénins d'un point de vue ASP.NET : vous devez créer une solution pour une opération d'extraction dans un magasin en ligne. Il existe des considérations spéciales à effectuer pour cette solution en raison de sa durée. Par exemple, vous pouvez choisir stocker les données panier d'achat dans une session d'ASP.NET. Vous pouvez même choisir déplacer cet état de session dans une base de données pour autoriser les mises à jour le site et équilibrage de charge ou état out-of-process server. Même ainsi, vous trouverez tous les outils que nécessaires pour résoudre ce problème facilement sont fournies pour par ASP.NET lui-même.
Toutefois, lorsque la durée de l'opération augmente plue le ASP.NET classique durée de session (20 minutes) ou nécessite plusieurs acteurs (comme dans mon exemple recrutement), ASP.NET n'offre pas suffisamment prise en charge. Vous pouvez rappeler que les processus de travail ASP.NET arrête automatiquement sur inactif et régulièrement recycler eux-mêmes. Cela entraînera gros problèmes pour les opérations de longue, comme état dans ces processus va être perdu.
Imaginez un moment que vous avez à ordinateur hôte ces très longues opérations à l'intérieur d'un seul processus. Clairement le processus de traitement ASP.NET ne convient pour eux pour les raisons simplement décrites pas. Donc peut-être il serait possible de créer un service windows dont seule responsabilité est pour pouvoir exécuter ces opérations. Si vous ne redémarrez ce service, vous ne serez plus proche d'une solution que si à l'aide d'ASP.NET directement, depuis simplement ayant un processus de service qui n'effectue pas automatiquement redémarrer théoriquement garantit que J'AI pas perdre l'état de mon opération de longue durée.
Mais se ce fait résoudre le problème ? Probablement pas. Que se passe-t-il si le serveur nécessite équilibrage de charge ? Qui est très difficile lorsque vous êtes lié à un seul processus. Pire, que se passe-t-il si vous avez de redémarrer le serveur ou le processus se bloque ? Puis toutes les opérations qui ont été exécute seront perdues.
En fait, lorsque vous opérations prendre jours ou semaines pour terminer, vous devez une solution qui est indépendante du cycle de vie du processus qui s'exécute elle. Dans ce cas en général, mais il est particulièrement important pour les applications Web ASP.NET.
Harnessing flux de travail
Windows Workflow Foundation (WF) peuvent ne pas être la technologie qui vient à l'esprit pour la création d'applications Web. Toutefois, il existe plusieurs fonctionnalités de clé fournies par WF qui rendent une solution de flux de travail important de considérer. WF vous permet d'obtenir indépendance de processus pour les opérations de longue en déchargement du flux de travail inactif entièrement de l'espace de processus et recharger automatiquement les dans le processus actif lorsqu'ils sont plus inactif (voir figure 1 ). L'aide de WF, vous pouvez augmentent ci-dessus le cycle de vie non déterministe du processus de traitement ASP.NET et fournir pour les opérations longue à l'intérieur de l'application Web.
Figure 1 flux de travail conserver opérations entre instances de processus
Deux fonctionnalités clés de pare-feu Windows se combinent pour fournir des fonctionnalités de ce. Tout d'abord, asynchrones activités signaler au runtime de workflow que le workflow est inactif pendant l'attente d'un événement externe. Ensuite, un service de persistance est décharger les workflows inactifs du processus de, enregistrez-le à un emplacement de stockage durable tel qu'une base de données et recharger le flux de travail lorsqu'elles sont prêtes exécuter à nouveau.
Cette indépendance a processus a autres avantages. Il fournit un moyen simple de équilibrage de charge ainsi durabilité, panne tolérance en face d'échecs de processus ou un serveur.
Activités synchrones et asynchrones
Activités sont des éléments atomiques de pare-feu Windows. Tous les workflows sont intégrées à partir d'activités dans un modèle ressemblant le motif de conception composite. En fait, les flux de travail eux-mêmes est activités simplement spécialisées. Ces activités peuvent être classées comme synchrone ou asynchrone. Une activité synchrone toutes ses instructions exécute du début à fin.
Exemple d'une activité synchrone peut être un calcule les taxes donné d'une commande dans un magasin en ligne. Nous allons considérer sur comment ce une activité peut être implémenté. Comme la plupart des activités WF, la majeure partie de travail s'effectue dans la méthode Execute substituée. Les étapes de cette méthode peuvent consultez présenter comme suit :
- Obtenir les données de commande à partir d'une activité précédente. Généralement cela via la liaison de données, et vous voir un exemple plus loin.
- Recherche du client associé à la commande à partir d'une base de données.
- Rechercher le taux d'imposition dans une base de données en se basant sur l'emplacement du client.
- Faire des certains calculs mathématiques simple appel au taux d'imposition et la commande les associés commande.
- Stocker le montant total des taxes dans une propriété qui activités suivantes peuvent lier à pour effectuer le processus de validation.
- Signal au runtime de workflow que cette activité est terminée en renvoyant l'indicateur d'état terminé l'exécution des méthodes.
Il est important à reconnaître que nulle part vous attendent. Vous utilisez toujours. La méthode Execute s'exécute à travers les étapes simplement et termine en bref ordre. C'est l'essence d'une activité synchrone : tout le travail est effectué dans la méthode Execute.
Activités asynchrones sont différentes. Contrairement à leurs homologues synchrones, activités asynchrones exécuter pour une période de temps et patientez sur un stimulus externe. Tout en attente, les activités devient inactives. Lorsque l'événement se produit, l'activité reprend l'opération et termine l'exécution.
Un exemple d'une activité asynchrone est une étape dans le processus de recrutement lorsqu'une application pour un poste doit être examinée par un responsable. Pensez à ce qui peut se produire si ce gestionnaire est en vacances et va avoir pas l'occasion d'examiner la candidature jusqu'à ce que la semaine prochaine. Il est complètement raisonnable à bloquer au milieu de la méthode Execute pendant l'attente de cette réponse. Lorsque le logiciel attend une personne, il devrez attendre longtemps. Vous devez prendre en compte ce dans votre conception.
Les exactement vous moyennes par inactif ?
À ce stade sémantique en anglais et la sémantique Architecture divergent. Prenons une étape en de pare-feu Windows et pensez plus généralement ce que signifie est plus inactif.
Examinez la classe suivante utilise un services Web pour modifier un mot de passe :
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;
}
}
La méthode ChangePassword est déjà inactif ? Si tel est le cas, où ?
Thread cette méthode est bloqué en attente d'une réponse HTTP du UserService. Donc théorie la réponse est Oui, le thread est inactif en attente de la réponse de service. Mais peut le thread en fait faire autres tâches pendant que vous attendez sur le service ? Non, pas comme elle est actuellement utilisée. Par conséquent, du point de vue du pare-feu Windows, ce workflow est jamais inactif.
Pourquoi est-ce jamais inactif ? Imaginez que vous avez une classe planificateur plue qui était d'exécuter des opérations telles que ChangePassword, efficacement. En efficacement, que je VEUX exécute plusieurs opérations en parallèle, utilisant le numéro minimum de threads requises pour le parallélisme complet et ainsi de suite. Il s'avère que la clé pour ce efficacité est de savoir lorsque l'opération s'exécute et lorsqu'il est inactif. Étant donné que lorsqu'une opération devient inactive, le planificateur pouvez utiliser le thread qui exécutait l'opération à effectuer des autres tâches que l'opération soit prête à exécuter à nouveau.
Malheureusement, la méthode ChangePassword est complètement opaque pour le planificateur de traitements. Car bien qu'il soit période il efficacement inactivité de, visualiser à partir de l'extérieur par le planificateur de cette méthode est une unité du blocage de travail. Le planificateur de traitements ne possède aucune fonctionnalité de fractionnement cette unité de travail séparée et de réutiliser le thread pendant la période d'inactivité.
Effectuer les tâches synchrones asynchrone
Vous pouvez ajouter cette nécessaire planification transparence à l'opération en fractionnant l'opération en deux parties : une qui exécute vers le point où l'opération est potentiellement inactive et qui exécute le code après l'état d'inactivité.
Dans l'exemple hypothétique illustré précédemment, vous pourriez utiliser les fonctionnalités asynchrones fournies par le proxy de service Web proprement dit. Gardez à l'esprit que ceci est une simplification et WF réellement fonctionne un peu différemment, comme vous le verrez dans une minute.
Dans la figure 2 , J'AI créé une version améliorée de la méthode de modification de mot de passe appelée ChangePasswordImproved. Je crée le proxy de service Web comme avant. Puis la méthode enregistre une méthode de rappel afin d'être prévenu lorsque le serveur a répondu. Ensuite, j'asynchrone exécute l'appel de service et indiquer pour le planificateur de traitements que l'opération est inactif, mais pas terminé, en renvoyant Status.Executing. Cette étape est importante, il s'agit de cette étape permet d'autres tâches effectuées par le planificateur tandis que mon code est inactif. Enfin, lorsque l'événement terminé se produit, j'appelle pour signaler que l'opération est terminée et pouvez déplacer sur le planificateur.
Appel de service simple mot de passe-modification de la figure 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 );
}
}
Flux de travail et activités
Je vais maintenant pour appliquer le concept d'une opération d'inactivité pour créer des activités de pare-feu Windows. Cela est très semblable à ce que vous avez vu précédemment, mais maintenant je devez travailler dans le modèle WF.
WF est livré avec de nombreuses activités intégrées. Toutefois, lorsque vous obtenez tout d'abord démarré créer des systèmes réels avec WF, vous rapidement souhaitez commencer à créer vos propres activités personnalisées réutilisables. Il est simple à faire. Vous définissez simplement une classe qui dérive de la classe Activity omniprésents. Voici un exemple simple :
class MyActivity : Activity {
override ActivityExecutionStatus
Execute(ActivityExecutionContext ctx) {
// Do work here.
return ActivityExecutionStatus.Closed;
}
}
Pour votre activité faire quoi que ce soit utile, vous devez remplacer la méthode Execute. Si vous créez une activité synchrone courte durée, vous simplement implémentez l'opération de votre activité à l'intérieur de cette méthode et renvoyer l'état Clôturé (E).
Il existe quelques problèmes plus important que les activités réelles sont susceptibles de prendre en compte. Mode de votre activité communication avec d'autres activités dans le flux de travail et la plus grande application hébergeant le flux de travail ? Comment il est pour accéder aux services tels que les systèmes de base de données, interaction de l'interface utilisateur et ainsi de suite ? Pour créer des activités synchrones, ces problèmes sont relativement simples.
Création d'activités asynchrones, en revanche, peut être une opération plus complexe. Heureusement, le motif utilisé est répété sur les activités plus asynchrones. En fait, vous pouvez capturer facilement ce modèle dans une classe de base, comme je le montrer dans un instant.
Voici les étapes de base nécessaires pour créer des activités plus asynchrones :
- Créez une classe qui dérive d'activité.
- Remplacer la méthode Execute.
- Créer une file d'attente du flux de travail pouvant servir pour recevoir une notification que l'événement asynchrone que vous avez été attendre est terminé.
- S'abonner à QueueItemAvailable événement la file d'attente.
- Lancer le début de l'opération longue (par exemple, envoyer un message vous demandant un responsable pour consulter une application pour un poste de travail).
- Attendre un événement externe se produise. Il signale efficacement l'activité est devenue inactive. Vous indiquer ce au runtime de workflow en renvoyant ExecutionActivityStatus.Executing.
- Lorsque l'événement se produit, la méthode gère l'événement QueueItemAvailable supprime l'élément de la file d'attente convertit le type de données attendu et traite les résultats.
- Généralement cela conclut opération l'activité. Le runtime de workflow est ensuite signalé en renvoyant ActivityExecutionContext.CloseActivity.
Persistance
Au début de cet article, je L'AI dit les deux tâches fondamentales nécessaires pour atteindre l'indépendance des processus via un flux de travail étaient des activités asynchrones et un service de persistance. Vous avez vu juste la partie activités asynchrones. Maintenant nous allons Explorer la technologie de persistance : services de flux de travail.
Services de flux de travail sont un point d'extensibilité clé pour le pare-feu Windows. Le runtime WF est une classe qui vous instanciez dans votre application pour l'exécution ordinateur hôte flux de travail. Cette classe a deux objectifs de conception opposer qui sont simultanément obtenues via le concept de services de flux de travail. L'objectif premier est pour cette exécution du workflow à un objet léger qui peut être utilisé à plusieurs endroits. L'objectif deuxième est pour cette runtime pour fournir des fonctions puissantes pour le flux de travail pendant qu'elles vous exécutent. Par exemple, il peut fournir la possibilité automatiquement conserver le flux de travail inactif, suivi du flux de travail et prendre en charge autres fonctionnalités personnalisées.
Le runtime de workflow reste léger par défaut, car seuls quelques ces fonctionnalités sont intégrées dans. Plusieurs services haute densité comme persistance et de suivi sont éventuellement installés via le modèle de service. En fait, la définition d'un service est toute fonctionnalité globale que vous souhaitez fournir à vos flux de travail. Vous installez ces services dans le service d'exécution en appelant simplement la méthode de AddService sur la classe WorkflowRuntime :
void AddService(object service)
Étant donné que AddService accepte une référence de System.Object, vous pouvez ajouter tout ce que le flux de travail peut être nécessaire.
Je vais pour travailler avec deux services. Tout d'abord, je vais utiliser WorkflowQueuingService pour accéder aux files d'attente du flux de travail qui sont fondamentales pour la création d'activités asynchrones. Ce service est installé par défaut et ne peut pas être personnalisé. L'autre service est SqlWorkflowPersistenceService. Ce service, bien sûr, fournira les capacités de persistance et il n'est pas installé par défaut. Heureusement, il est inclu avec WF. Vous devez simplement ajouter au runtime.
Par un nom comme SqlWorkflowPersistenceService, vous pouvez parie qu'une base de données seront requis quelque part. Vous pouvez créer une base de données vide dans ce but ou vous pouvez ajouter des tables à une base de données existante. Je préfère personnellement utiliser une base de données dédiée plutôt que de discuter des données de persistance du flux de travail avec mes autres données. Ainsi, je créer une base de données vide dans SQL Server appelée WF_Persist. JE créer le schéma de base de données nécessaires et les procédures stockées en exécutant plusieurs scripts. Ils sont installés dans le cadre de Microsoft .NET Framework et sont par défaut situé dans ce dossier :
C:\Windows\Microsoft.NET\Framework\v3.0\Windows du flux de travail Foundation\SQL\EN\
Vous souhaitez exécuter le script SqlPersistenceService_Schema.sql tout d'abord et puis exécutez le script SqlPersistenceService_Logic.sql. Je peux maintenant utiliser cette base de données de persistance en transmettant la chaîne de connexion au service de persistance :
SqlWorkflowPersistenceService sqlSvc =
new SqlWorkflowPersistenceService(
@"server=.;database=WF_Persist;trusted_connection=true",
true, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
wfRuntime.AddService(sqlSvc);
Cet appel de méthode AddService simple est tout requis pour commencer le déchargement du flux de travail inactif et les stocker dans la base de données et les restaurer lorsqu'ils sont nécessaires à nouveau.Le runtime WF s'occupe de tout le reste.
Rendre son réel
Maintenant que vous avez assez des techniques underpinnings en place, vous pouvez tissé qu'ensemble créer un site Web ASP.NET prenant en charge les opérations longue.Les trois éléments principales qui s'affichera dans cet exemple sont la création d'activités asynchrones, intégrant le runtime de workflow dans l'application Web et communiquer avec le flux de travail à partir des pages Web.
Je vais travailler avec une hypothétique société de conseil de .NET appelée Trey Research.Il souhaite automatiser le processus recrutement et recrutement pour les consultants.Donc je va peut-être générer un site Web ASP.NET pour prendre en charge ce processus de recrutement.Je vais faire choses très simple, mais il existe plusieurs étapes du processus :
- Un candidat de travail visitez Trey Research site et express intérêt pour un travail.
- Un message électronique sera envoyé au responsable de noter qu'il y a un nouveau candidat.
- Ce gestionnaire est examiner la candidature et approuver le candidat pour un poste spécifique.
- Un message électronique sera envoyé le candidat avec des informations sur le poste proposé.
- Le candidat est visiter le site Web et soit accepter ou rejeter la position.
Si ce processus est simple, il existe plusieurs étapes où l'application attend d'une personne revenir et remplir quelques informations.Ces points inactifs peuvent prendre du temps.Ils sont donc idéal pour illustrant un processus long terme.
Cette application Web est incluse dans le code source pour l'article.Toutefois, pour voir l'effet complet vous devrez créer la base de données de persistance et configurer l'exemple pour l'utiliser.J'ai créé un commutateur pour indiquer si le service de persistance est en ou désactivée et avez défini qu'il soit désactivé par défaut.Pour activer, configurer usePersistDB sur true dans la section AppSettings de web.config.Si vous souhaitez voir au cours qui vous lire, vous pouvez afficher laVisionneuse de travail asynchroneexécuter sur mon site Web.
La figure 3, le processus de recrutement comme un flux de travail
Je commence par concevoir le flux de travail totalement indépendant à partir d'ASP.NET.Pour créer le flux de travail, je créerai quatre activités personnalisées.La première est une activité de messagerie d'envoi et sera une simple activité synchrone.Les trois autres représentent les étapes 1, 3 et 5 illustrée précédemment et seront activités asynchrones.Ces activités sont les clés à la réussite de l'opération longue.J'AI s'appeler ces GatherEmployeeInfoActivity, AssignJobActivity et ConfirmJobActivity, respectivement.J'AI est ensuite combiner ces activités dans le workflow bones Il est vrai simple illustré figure 3 .
L'activité de courrier électronique envoyer est simple donc je ne vais pas dans les détails de cette activité dans cet article.Il est une activité synchrone à la classe MyActivity illustrée précédemment.Observez le téléchargement de code pour plus d'informations.
Cela laisse me à la création les trois activités asynchrones.Je gagner moi-même beaucoup de travail si je peut encapsuler que huit-processus étape de création d'une activité asynchrone dans une classe de base commune.Pour ce faire, j'est définir une classe appelée AsyncActivity (voir figure 4 ).Notez que cette liste n'inclut pas plusieurs méthodes d'assistance interne ou qui traitement d'erreur est présente dans le code réel.Les détails le ont été omis par souci de souci de concision.
La figure 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);
}
Dans cette classe de base, vous verrez que j'encapsulée plusieurs les parties fastidieuses et répétitives de création d'une activité asynchrone. Exécutons à cette classe de haut en bas. À partir du constructeur, je transmets dans une chaîne pour le nom de file d'attente. Files d'attente du flux de travail sont les points en entrée pour l'application ordinateur hôte les pages Web transmettre des données dans les activités tout en restant faiblement couplé. Ces files d'attente sont désignées par exemple nom et le flux de travail, pour chaque activité asynchrone doit son propre nom de file d'attente distinct.
Ensuite, je définir la méthode GetQueue. Comme vous pouvez le voir, l'accès à et la création du flux de travail files d'attente sont facile, mais un peu fastidieux. J'AI créé cette méthode comme une méthode d'assistance pour une utilisation au sein de cette classe et que vous classes dérivées.
Je puis définir une méthode appelée SubscribeToItemAvailable. Cette méthode encapsule les détails de s'abonner à l'événement déclenché quand un élément arrive dans la file d'attente de flux de travail. Cela représente presque toujours l'exécution d'une longue attente période dans laquelle le flux de travail a été inactif. Ainsi, le cas d'utilisation va présenter comme suit :
- Commencer longues opération et appelez SubscribeToItemAvailable.
- Indiquer le runtime de workflow que l'activité est inactive.
- L'instance de workflow est sérialisé vers la base de données par le service de persistance.
- Lorsque l'opération terminée, un élément est envoyé à la file d'attente de flux de travail.
- Cela déclenche l'instance de workflow à restaurer à partir de la base de données.
- La méthode abstraite modèle OnQueueItemAvailable est exécutée par le AsyncActivity base.
- L'activité termine son opération.
Pour visualiser cette classe AsyncActivity en action, nous allons implémenter la classe AssignJobActivity. Deux autres activités asynchrones sont similaires et sont incluses dans le téléchargement de code.
Dans la figure 5 , vous pouvez voir comment AssignJobActivity utilise le modèle fourni par la classe de base AsyncActivity. JE remplace exécuter pour effectuer tout travail préliminaire pour commencer l'activité longue, s'il n'y dans ce cas a vraiment pas un. Alors que je s'abonner à l'événement pour lorsque plus de données sont disponibles.
La figure 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;
}
}
Il existe un implicite contrat ici, que l'application ordinateur hôte, la page Web, s'envoyer dans un nouvel objet de travail en file d'attente de l'activité lorsqu'il a recueilli ces informations dans le gestionnaire. Cela est signaler l'activité qui il convient de continuer. Il met à jour l'employé dans la base de données. L'activité suivante dans le flux de travail s'envoyer un message électronique à l'employé potentiel lui indiquant que ce travail est proposée pour sa position.
Intégration avec ASP.NET
C'est son fonctionnement dans le flux de travail. Mais comment début du flux de travail ? Comment la page Web en fait rassembler l'offre de travail du gestionnaire ? Comment il de transmettre la tâche à l'activité ?
Premières choses premier : voyons comment faire pour démarrer le flux de travail. Dans la page pour le site Web de destination existe une liaison appliquer. Lorsque le candidat clique sur ce lien, il démarre le workflow et la navigation via l'interface utilisateur en parallèle :
protected void LinkButtonJoin_Click(
object sender, EventArgs e) {
WorkflowInstance wfInst =
Global.WorkflowRuntime.CreateWorkflow(typeof(MainWorkflow));
wfInst.Start();
Response.Redirect(
"GatherEmployeeData.aspx?id=" + wfInst.InstanceId);
}
J'AI simplement appelez CreateWorkflow sur le runtime de workflow et démarrer l'instance de flux de travail. Ensuite j'assurer le suivi de l'instance de flux de travail en transmettant l'ID instance à toutes les pages Web suivantes comme paramètre de requête.
Comment envoyer les données à partir de la page Web dans le flux de travail ? Examinons la page de travail affecté, dans la figure 6 , où un gestionnaire choisit un travail pour un candidat.
La figure 6 affectation d'une tâche
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 page Affectation travail Web est largement simplement un formulaire entrée simple. Il comprend une liste déroulante des tâches disponibles et une zone de texte pour le salaire proposé. Elle affiche également le candidat en cours, bien que ce code est omis de la liste. Lorsque le responsable affecte une position et le salaire du candidat, il est sur le bouton d'envoi et exécutez le code dans la figure 6 .
Cette page utilise l'ID d'instance du flux de travail comme un paramètre de chaîne de requête pour rechercher l'instance de workflow associé. Un objet de traitement est ensuite créé et initialisé avec les valeurs de l'écran. Enfin, j'envoyer ces informations dans l'activité en enqueuing le travail en file d'attente de cette activité. C'est l'étape clé qui recharge le workflow inactif et qui permet à continuer l'exécution. AssignJobActivity s'associer ce travail à l'employé précédemment collectée et les enregistrer dans une base de données.
Ces listes deux derniers code Insistez sur workflow comment fondamental files d'attente doivent la réussite d'activités asynchrones et la communication du flux de travail avec la ordinateur hôte extérieur. Il est également important de noter que l'utilisation de flux de travail n'a ici aucun impact sur la page flux. Même si je peut également utiliser pare-feu Windows pour contrôler le flux de page, il est tout simplement pas l'objectif de cet article.
Dans La figure 6 , vous l'avez vu que J'AI accessible le runtime de workflow via la classe application globale, comme suit :
WorkflowInstance wfInst =
Global.WorkflowRuntime.GetWorkflow(id);
Cela m'amène au point final d'intégration de Windows Workflow dans notre application Web : tous les workflows exécuter dans le runtime de workflow. Bien que vous puissiez disposer d'autant d'exécution du flux de travail que vous le souhaitez dans votre domaine d'application, il souvent opportun d'ont un runtime de workflow simple. De ce fait, et car l'objet d'exécution WF est thread-safe, J'AI il effectué une propriété publique statique de la classe application globale. En outre, J'AI démarrer le runtime de workflow dans l'événement de démarrage application et arrêter dans l'événement Arrêt application. la figure 7 est une version abrégée de la classe application globale.
La figure 7 démarrage de l'exécution du flux de travail
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.
}
}
Dans l'événement de début application, J'AI créer le runtime, installer le service de persistance et démarrez le service d'exécution.Et dans l'événement fin de l'application, J'AI arrêter le service d'exécution.Il s'agit d'une étape importante.Il se bloquera si il exécutent les flux de travail jusqu'à ce que ces flux de travail ont été déchargé.Après l'arrêt de l'exécution, j'appelle dispose.Si l'appel à StopRuntime puis à dispose peut sembler redondante, il n'est pas.Vous devez appeler les méthodes dans cet ordre.
A choses à réfléchir
Laissez-moi vous donner quelques éléments à penser que je n'a pas directement toucher, présentées dans format question et réponse.Pourquoi n'a pas utiliser ManualWorkflowSchedulerService ?Souvent lorsque personnes parler d'intégration de WF avec ASP.NET ils Soulignez que vous devez remplacer le planificateur par défaut pour les flux de travail (qui utilise le pool de threads) par un service appelé ManualWorkflowSchedulerService.La raison est car il n'est pas requis ou réellement approprié pour nos objectifs longues.Le planificateur manuel convient lorsque vous prévoyez d'exécuter un workflow simple jusqu'à la fin d'une demande donnée.Il est moins utile lorsque votre flux de travail est exécutez sur processus de durées de vie, ne pas de préciser via des demandes.
Y a-t-il un moyen pour suivre la progression actuelle d'une instance de workflow donné ?Oui, il est un ensemble de service de suivi intégré à WF et elle est utilisée de manière similaire comme le service de persistance SQL.Afficher la colonne Foundations mars 2007 »Suivi des services dans Windows Workflow Foundation« Par Matt Milner.
Il collecte tous ensemble
J'AI pouvez résumer les techniques décrits dans cet article avec quelques étapes.J'AI commencé par plan pourquoi les processus de travail ASP.NET et le modèle de processus en général ne conviennent pas très longues opérations.À retournez cette limitation J'AI tiré parti de deux fonctionnalités de pare-feu Windows qui sont combinées pour atteindre l'indépendance des processus : Activités asynchrones et la persistance du flux de travail.
Création d'activités asynchrones pouvant être un peu compliquée, J'AI encapsulé les détails dans la classe de base AsyncActivity introduite dans cet article.Puis j'exprimé l'opération de longue comme un workflow séquentiel créé avec activités asynchrones que je peux incorporer que dans une application Web et obtenir gratuitement indépendance de processus.
Enfin, J'AI démontré qu'intégration le flux de travail ASP.NET est simple en deux parties : communiquer avec les activités via une file d'attente du flux de travail et hébergement de l'exécution de la classe application globale.
Maintenant que vous avez vu pare-feu Windows intégré à ASP.NET pour prendre en charge les longues opérations, vous avez un outil plus puissant pour créer des solutions en haut du .NET Framework.
Michael Kennedy est formateur pour DevelopMentor où il est spécialisé dans les technologies .NET principaux ainsi agile et méthodologies de développement TDD.Maintenir Michael via son site Web et le blog à michaelckennedy. NET.