2009-08-23 16 views
26

¿Cómo puedo implementar colas de procesamiento en segundo plano en mi aplicación web ASP.NET MVC? Si bien la mayoría de los cambios de datos, actualizaciones, etc. deben ser visibles de inmediato, existen otras actualizaciones que no necesitan procesamiento en tiempo real que me gustaría transferir a un proceso en segundo plano de menor prioridad que lo resolverá a su propio ritmo. .Procesamiento en segundo plano basado en cola en la aplicación web ASP.NET MVC

Como ejemplo, tome el sistema de concesión de distintivos de StackOverflow. Por lo general, puede realizar una acción específica que le otorgue una insignia, pero el 'premio' real ocurre más tarde (generalmente entre 10 minutos y un par de horas más tarde). Supongo que esto se hace a través de un proceso de fondo separado, ya que no es crítico para el funcionamiento de SO otorgar insignias de inmediato cuando se gana.

Por lo tanto, estoy tratando de crear algún tipo de sistema de cola en el que pueda completar tareas (digamos cualquier cosa que implemente la interfaz ITask que tendrá un método Process) que eventualmente será ejecutado por un proceso separado.

¿Cómo podría implementar este sistema? Ideas/Sugerencia/Código de muestra?

¡Gracias!

Respuesta

20

Servicios de Windows y MSMQ para comunicarse con ellos (incluso si es necesario).

- Editar

Expandir ligeramente.

Creará varios servicios, según lo que desee hacer, y hará que todos ejecuten un hilo interminable de varios niveles de inactividad, para hacer lo que desee. A continuación, actualizarán la base de datos de forma adecuada y no habrá tenido que hacer nada en el lado del cliente.

Es posible que desee interactuar con ellos desde el punto de vista del administrador, por lo tanto, es posible que tenga un MSMQ en el que escuchen los comandos de administración. Dependiendo de su implementación, es posible que deba reiniciarlos por alguna razón, o posiblemente simplemente 'forzar' la ejecución de lo que quieran hacer.

Así que usará una cola privada MSMQ para hacerlo (espacio de nombres System.Messaging). Una de las cosas principales a tener en cuenta sobre MSMQ es que el mensaje debe ser < 4meg. Entonces, si tiene la intención de enviar gráficos de objetos grandes, primero haga una serialización a un archivo y simplemente envíe el nombre del archivo.

MSMQ es bastante hermoso. Puede enviar basada en un 'identificador de correlación' si es necesario, pero, por alguna razón, divertida, el ID de correlación debe ser en forma de:

{guid}\1 

Cualquier otra cosa no funciona (al menos en la versión 2.0 del marco, el código puede haber cambiado).

- Editar

ejemplo, conforme a lo solicitado:

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

¿Tiene usted un ejemplo de cómo inicialmente una aplicación de servicio de 'conectar' con un MSMQ y luego a ASP.NET MVC? Esto es bastante nuevo para mí. ¡Gracias! – Alex

+0

Usted solo escribe en la cola apropiada. Su servicio llamará a .Receive y su página, de la que desea enviar un mensaje a la cola, simplemente llamará a '.Send'. Voy a actualizar con un pequeño ejemplo. –

+0

Actualizado. Tenga en cuenta que no he mostrado el código para crear la cola, si no existe. Pero eso se puede encontrar de manera trivial simplemente tomando un me gusta en System.Messaging API. Específicamente: MessageQueue.Create (...). Tenga en cuenta que también necesitará obtener los permisos adecuados. (.Establecer permisos). –

10

Jeff tiene un gran post que muestra cómo se logra esto originalmente para el desbordamiento de pila en http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

Aunque podría no ser tan fiable como un servicio, si esa es una opción para usted, me ha sido útil en el pasado para tareas no esenciales, y lo he tenido funcionando en un entorno de alojamiento virtual.

5

Acabo de encontrar esta pregunta al buscar el proceso de fondo en ASP.NET MVC. (Disponible después de .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); 
} 

Nota: En lo personal no voy a utilizar el servidor web para ejecutar tareas en segundo plano. Además, no reinvente la rueda, recomendaría utilizar Hangfire.

Lee este genial artículo de Hanselman HowToRunBackgroundTasksInASPNET

Cuestiones relacionadas