2009-08-23 6 views
26

Comment puis-je implémenter des files d'attente de traitement en arrière-plan dans mon application Web ASP.NET MVC? Alors que la plupart des changements de données, mises à jour etc. doivent être visibles immédiatement, il y a d'autres mises à jour qui n'ont pas besoin de traitement en temps réel que je voudrais passer à un processus de fond de moindre priorité qui s'en chargera à son propre rythme . Par exemple, prenez le système d'attribution de badges de StackOverflow. Habituellement, vous pouvez prendre une action spécifique qui vous donnerait un badge, mais la «récompense» réelle arrive plus tard (généralement entre 10 minutes et quelques heures plus tard). Je suppose que cela se fait via un processus d'arrière-plan distinct, car il n'est pas essentiel pour les travaux de SO d'attribuer des badges immédiatement lorsqu'ils sont gagnés. Donc, j'essaie de créer une sorte de système de files d'attente dans lequel je pourrais bourrer des tâches (dire n'importe quoi implémentant l'interface ITask qui aura une méthode Process()) qui sera finalement exécutée par un processus séparé.Traitement en arrière-plan basé sur une file d'attente dans une application Web ASP.NET MVC

Comment procéder pour mettre en place un tel système? Idées/Indice/Code d'échantillon?

Merci!

Répondre

20

Services Windows et MSMQ pour communiquer avec eux (si vous en avez même besoin).

- Édition

Pour développer légèrement.

Vous allez créer plusieurs services, en fonction de ce que vous voulez faire, et les faire tous tourner un fil sans fin de différents niveaux de sommeil, pour faire ce que vous voulez. Ils vont ensuite mettre à jour la base de données de manière appropriée, et vous n'aurez pas à faire quoi que ce soit du côté client.

Vous souhaiterez peut-être interagir avec eux d'un point de vue administrateur, vous pouvez donc avoir un MSMQ sur lequel ils écoutent les commandes d'administration. Selon votre implémentation, vous devrez peut-être les redémarrer pour une raison quelconque, ou peut-être juste "forcer" une exécution de tout ce qu'ils souhaitent faire. Par conséquent, vous utiliserez une file d'attente privée MSMQ pour le faire (espace de noms System.Messaging). Une des principales choses à noter à propos de MSMQ, est que ce message doit être < 4meg. Donc, si vous avez l'intention d'envoyer des graphiques d'objets volumineux, commencez par sérialiser dans un fichier et envoyez simplement le nom de fichier.

MSMQ est très belle. Vous pouvez envoyer basée sur un « ID de corrélation » si vous avez besoin, mais, pour une raison amusante, l'ID de corrélation doit être sous la forme de:

{guid}\1 

Tout autre ne fonctionne pas (au moins dans la version 2.0 du cadre, le code peut avoir changé).

- Modifier

Exemple, comme l'a demandé:

using System.Messaging; 

... 


MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue"); 
queue.Formatter = new BinaryMessageFormatter(); 

Message m = new Message(); 
m.Body = "your serialisable object or just plain string"; 

queue.Send(m); 


// on the other side 

MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue"); 
queue.Formatter = new BinaryMessageFormatter(); 

Message m = queue.Receive(); 

string s = m.Body as string; 

// s contains that string now 
+1

Avez-vous un exemple sur la façon d'abord « connecter » une application de service avec un MSMQ, puis à ASP.NET MVC? C'est assez nouveau pour moi. Je vous remercie! – Alex

+0

Vous venez d'écrire dans la file d'attente appropriée. Votre service appellera .Receive et votre page, que vous voulez envoyer un message à la file d'attente, appellera simplement '.Send'. Je vais mettre à jour avec un petit exemple. –

+0

Mis à jour. Remarque: Je n'ai pas montré le code pour créer la file d'attente, si elle n'existe pas. Mais cela peut être trivialement trouvé juste en prenant un comme à l'API System.Messaging. Plus précisément: MessageQueue.Create (...). Notez que vous devrez également obtenir les autorisations appropriées. (.SetPermissions). –

10

Jeff a un grand poste montrant comment il a obtenu cette origine pour débordement de pile à http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

Bien qu'il pourrait ne pas être aussi fiable En tant que service, si c'est une option pour vous, cela m'a bien servi dans le passé pour des tâches non essentielles, et je l'ai eu dans un environnement d'hébergement virtuel.

5

Je viens de trouver cette question lors de la recherche de processus d'arrière-plan dans ASP.NET MVC. (Disponible après .NET 4.5.2)

public ActionResult InitiateLongRunningProcess(Emails emails) 
{ 
    if (ModelState.IsValid) 
    { 
     HostingEnvironment.QueueBackgroundWorkItem(ct => LongRunningProcessAsync(emails.Email)); 
     return RedirectToAction("Index", "Home"); 
    } 

    return View(user); 
} 

Remarque: Personnellement, je n'utiliserai pas le serveur Web pour exécuter des tâches d'arrière-plan. Aussi, ne pas réinventer la roue, je recommande fortement d'utiliser Hangfire.

Lire cet article de Hanselman HowToRunBackgroundTasksInASPNET

Questions connexes