2011-04-11 8 views
7

I tienen dos métodos (en C#):Pizza, Enhebrado, Esperando, Notificar. Qué significa eso?

List<Pizza> CookPizza(List<Order>); 
List<HappyCustomers> DeliverPizza(List<Pizza>); 

Estas operaciones no tienen objetos comunes (aparte de las pizzas que se transmiten de uno a otro), y son thread-safe. Cada uno de ellos toma varios segundos para ejecutarse y cada uno usa diferentes recursos (horno frente a automóvil). Como tal, quiero ejecutarlos al mismo tiempo.

¿Cómo organizo el roscado con estas restricciones:

  • Sé que todos los pedidos en el inicio (por ejemplo, tengo 100.000 de ellos). Una orden puede consistir en varias pizzas y no sé cuántas pizzas hay en una orden hasta que esas pizzas estén cocidas. (extraño, lo sé). En general, un pedido tiene 1 pizza, pero puede haber hasta 10.

  • El número de pizzas activas generalmente no debe superar las 100. Esto incluye las pizzas recién horneadas y las pizzas que se entregan. Este es un límite suave, así que puedo excederlo un poco (por ejemplo, cuando se cocinó una gran orden). El límite difícil es probablemente más cercano a 500.

  • Ambas operaciones son más eficientes cuando se les da mucho trabajo. En general, CookPizza es más eficiente cuando se le dan al menos 20 pedidos. La entrega de pizza es más eficiente cuando se le dan al menos 50 pizzas. Es decir, veré la degradación del rendimiento si doy menos elementos a esos métodos que esos montos. Está bien usar menos elementos si eso es todo lo que queda.

El problema principal con el que estoy luchando es cómo los métodos pueden necesitar esperar el uno del otro.

  • DeliverPizza podría tener que esperar a que se complete CookPizza 50.
  • CookPizza podría tener que esperar en torno a DeliverPizza para reducir el número de pizzas activos a 100.
+0

¿Los métodos deben tener esas firmas? – jgauffin

+11

+1 si hizo clic en este enlace debido a la palabra PIZZA –

+0

@jgauffin, no. ¿Qué tienes en mente? –

Respuesta

4

Me gustaría abordar este problema usando un modelo basado en eventos para empezar.

Digamos que tenemos un objeto PizzaDispatcher que recibe los pedidos. El despachador comienza a llamar al CookPizza con un número determinado de órdenes desde el estado vacío inicial. Cuando se cocinan las pizzas, la función CookPizza notifica al despachador que se ha cocinado una pizza (quizás mediante una devolución de llamada que proporcione como parámetro). Cuando se entrega una pizza, la función DeliverPizza hace lo mismo.

El PizzaDispatcher ahora tendría suficiente información para decidir cuándo y cuántas pizzas se deben entregar para cocinar o para entregar en función de la cantidad de pizzas cocidas y las entregas pendientes.

Esto se puede refactorizar para usar eventos en lugar de devoluciones de llamada, etc., pero lo estoy publicando para la idea, no los detalles de la implementación.

+0

Ahora tengo un prototipo sucio y funcional. ¡Gracias! –

0

se pensaba

agrega una variable miembro a Pizza para rastrear is_cooked. luego, durante CookPizza, configure ese miembro como verdadero cuando termine, y luego durante DeliverPizza, verifique ese miembro antes de continuar.

+0

Mejor creo que para rastrear el estado de pizza en qué cola está. Cuando se entregan simplemente elimine el objeto de pizza o colóquelo en una cola entregada. –

4

Desea un búfer simultáneo, probablemente una cola concurrente, y puede necesitar varios. Desea una cola concurrente de pedidos. Llama a CookOrder con la cola simultánea. Cuando CookOrder regresa, lo vuelve a llamar con los nuevos contenidos de la cola. Aquí solo puede publicar los primeros 100 artículos o algo si lo desea. Aquí los pedidos están efectivamente agrupados por la cola y CookOrder siempre se está ejecutando. Luego repites el proceso nuevamente con Pizzas.

+0

He votado a favor, pero ... el mero hecho de tener una colección segura no ayuda con la señalización que tengo que hacer. –

1

Parece que todo lo que necesita es un PizzaManager que decida qué Pizza para cocinar primero, y luego los pasa junto con el DeliveryBoy para que sean entregados. Luego, una vez que DeliveryBoyDeliversPizza, informa al PizzaManager para recuperar el siguiente pedido Pizza. El PizzaManager se ocupa de todas las matemáticas relacionadas con la optimización de la prioridad de las órdenes de cocinar y entregar. El DeliveryBoy probablemente tenga el PizzaManager como delegate.

Cuestiones relacionadas