2012-04-30 19 views
6

Actualmente estoy trabajando en un sitio de comercio electrónico y hay una característica que no estoy muy seguro de cómo implementarla. La mayoría de las veces solo agrega producto (s) a su carrito y los compra, ese es probablemente el flujo de trabajo más simple. Lo que estoy preguntando es un poco diferente, ¿qué pasa si hay un límite de tiempo para comprar un producto? Me refiero a que algunos sitios te dan un límite de tiempo exacto para comprar un producto (como Soccer Manager), en esos sitios no puedes tener un producto para siempre, hay un límite de 15 minutos para él y si no compras en ese período, el artículo ser liberado de su carrito (y muy probablemente otra persona saltará sobre él)¿Cómo hacer trabajos en segundo plano en un sitio ASP.NET MVC 3?

Ahora, como programador ASP.NET MVC, me encantaría implementar esta característica, pero como dije, no estoy seguro de cómo hacerlo. Creo que cuando agregue el artículo al carro necesito mantener el tiempo (algo así como ItemAddedAt) y necesito liberar ese artículo en x minutos para que algo tenga que ejecutarse x minutos más tarde para lanzar ese producto. Pensando globalmente, creo que necesito un servicio, cuando agrego un artículo, también necesito suscribirlo a este servicio y el servicio ejecuta un temporizador/trabajo en segundo plano. Lo que no sé/no tengo experiencia es esta parte, cómo hacer eso en un proyecto ASP.NET MVC, ¿hay algún proyecto de muestra, artículo, biblioteca o algo así?

Por supuesto que no sé si mi lógica es la correcta para este problema, necesito alguna guía, si es posible, algún código fuente para trabajar.

Respuesta

4

AFAIK no hay una manera estándar de declarar/programar tareas dentro de un proyecto MVC. La forma recomendada de lograr lo que desea sería crear un nuevo proyecto de Aplicación de consola dentro de su solución, y usar el Programador de tareas de Windows para ejecutar cada X minutos, liberando cualquier producto que haya sido más de X minutos en cualquier carrito.

Para que esto funcione, necesitará hacer referencia a su proyecto MVC desde el nuevo (para tener acceso a todos los modelos) o, mejor aún, crear un proyecto de biblioteca de clase, mover sus clases de modelo/base de datos allí, y referenciarlo desde los proyectos de MVC y Consola.


dicho todo esto, no es en realidad un pequeño "hack" que puede ser utilizado para obtener las tareas programadas en un proyecto de MVC. Usted puede utilizar el siguiente código:

HttpContext.Current.Cache.Add("Task", "1", null, 
      DateTime.MaxValue, TimeSpan.FromMinutes(5), 
      CacheItemPriority.Normal, new CacheItemRemovedCallback(CheckCarts)); 

Esa línea, que podría llamarse, por ejemplo, desde el Global.asax, sería añadir una entrada de "tareas" en la memoria caché. El valor almacenado ("1") no es importante, lo importante es que la entrada de caché expira en cinco minutos y, cuando expira, llama al método "CheckCarts" (definido en Global.asax, o en la clase donde ejecutaste este código).

public void CheckCarts(string key, object value, CacheItemRemovedReason reason) { 
    // Insert your code here to check for expired carts 
    (...) 

    // We add the entry again to the cache, so that this method will be called again in 5 minutes. 
    HttpContext.Current.Cache.Add("Task", "1", null, 
      DateTime.MaxValue, TimeSpan.FromMinutes(5), 
      CacheItemPriority.Normal, new CacheItemRemovedCallback(CheckCarts)); 
} 

Cuando expira la memoria caché, el método CheckCarts se llama, su código hace lo que tiene que hacer, y al final se agrega a la caché de nuevo, que se llamará en otros 5 minutos.

+0

Antes que nada, gracias por la explicación detallada ^^ Creo que no preferiré el Programador de tareas de Windows porque de lo que entiendo, si uso Scheduler de esa manera, entonces necesito ejecutar ese servicio con períodos muy cortos o Habrá grandes diferencias de tiempo entre el tiempo de caducidad y el próximo tiempo de ejecución programado. En mi humilde opinión, su segunda solución es más emocionante porque le da un disparador exacto y parece que puede implementarse fácilmente, pero hay una pregunta en mi mente: ¿es CacheItemRemovedCallback lo suficientemente confiable como para usar en este tipo de soluciones? –

+0

ese tipo de implementación recursiva también podría funcionar, pero de inmediato comencé a preocuparme por el tamaño de la pila de llamadas en este caso –

+0

@ArtemNikolov Usamos ese código exactamente por el mismo motivo (actualmente está trabajando en un comercio electrónico, por liberando acciones), y se ha estado ejecutando durante unos 4 años, así que supongo que sí :) – salgiza

3

Este escenario solo grita signalR. Te permitiría hacer lo que estás preguntando de una manera simple.

Si los artículos en su carrito tienen una fecha de vencimiento, podría tener su encuesta de vista si algún artículo ha expirado. Si lo tienen, puede ejecutar el código de eliminación para ese artículo y actualizar su interfaz de usuario.

+1

Estoy de acuerdo. La eliminación no importa hasta que intente ver su carrito. Entonces, ¿por qué ejecutar este proceso en segundo plano? Simplemente verifique el vencimiento del carrito antes de mostrarlo. Esto también le ahorrará el trabajo de caducar carros abandonados. Y le ahorrará tener que supervisar un conjunto de trabajos por lotes para asegurarse de que se estén ejecutando. –

+0

@spaceman: Me aseguraré de investigar sobre SignalR, una biblioteca en tiempo real como esa podría funcionar bien aquí y puedes hacer algunos buenos trucos de UX. –

+0

@Brian: Creo que hay un ligero malentendido acerca de esta eliminación, no se trata del carro del comprador, sino de las existencias de ese producto. Después del vencimiento, debe liberar ese producto para que otra persona pueda comprarlo, hasta ese momento debe mostrarle un botón de compra desactivado porque el artículo aún está reservado. Por supuesto, para cada solicitud debe verificar su inventario de todos modos, pero ahora su servicio de administrador de inventario también deberá verificar el vencimiento de ese artículo reservado. En lugar de eso, quiero que el producto envíe la señal de vencimiento para poder disminuir la mensajería interna entre los componentes. –

Cuestiones relacionadas