2011-04-11 113 views
7

我有两个方法(在C#):披萨,线程,等待,通知。这是什么意思?

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

这些操作(从从一个传递到另一个比萨饼除外)没有共同的目标,并且是线程安全的。他们每个人需要几秒钟才能执行,他们每个人都使用不同的资源(烤箱vs汽车)。因此,我想同时运行它们。

如何整理穿线这些限制:

  • 我知道所有的订单在启动(比方说,我有他们的100,000)。订单可以由多个比萨饼组成,我不知道有多少比萨饼在任何订单中,直到这些比萨饼被煮熟之后。 (我知道的很奇怪)。通常一个订单有1个比萨饼,但最多可以有10个。

  • 活动比萨饼的数量一般不应超过100.这包括比萨饼新鲜烹制的比萨饼正在交付。这是一个软限制,所以我可以超过它(例如,当一个大订单煮熟时)。硬限制可能接近500.

  • 这两种操作在进行大量工作时效率更高。一般来说,CookPizza在提供至少20份订单时效率最高。送至少50份披萨时,送披萨最为有效。也就是说,如果我给这些方法的项目数量少于这些数量,我会看到性能下降。如果剩下所有东西,就可以使用更少的项目。

我一直在努力的主要问题是方法可能需要彼此等待。

  • DeliverPizza可能需要等待周围CookPizza完成50
  • CookPizza可能需要等待周围DeliverPizza活跃比萨饼的数量减少到100
+0

这些方法是否必须具有这些签名? – jgauffin 2011-04-11 12:34:37

+11

+1如果你点击这个链接,因为字PIZZA – 2011-04-11 12:46:06

+0

@jgauffin,no。你有什么考虑? – 2011-04-11 16:25:11

回答

4

我会用一个基于事件的模型来解决这个问题。

假设我们有一个给定订单的PizzaDispatcher对象。调度员从最初的空状态开始以一定数量的订单呼叫CookPizza。当比萨饼煮熟时,CookPizza函数通知调度员比萨已煮熟(可能通过您提供的回调作为参数)。当披萨交付时,DeliverPizza功能也一样。

PizzaDispatcher现在将有足够的信息来决定什么时候和多少匹比萨应该打开烹饪或交付基于熟比萨饼和杰出的交付数量。

这可以重构为使用事件而不是回调等,但我发布它的想法,而不是实现的细节。

+0

我现在有一个工作,凌乱的原型。谢谢! – 2011-04-11 17:55:57

0

想到

向比萨添加一个成员变量来跟踪is_cooked。 然后在CookPizza期间,完成时将该成员设置为true,然后在DeliverPizza期间 ,在继续之前检查该成员。

+0

更好的是我想通过它的队列来跟踪比萨状态。交付时只需删除比萨饼对象或放置在交付队列中。 – 2011-05-18 23:19:19

4

你想要一个并发缓冲区 - 可能是一个并发队列,你可能需要几个。你想要一个并发的订单队列。您可以使用并发队列调用CookOrder。当CookOrder返回时,您再次使用队列的新内容调用它。在这里,你只能发布前100个项目或其他东西,如果你想。这里的订单是有效地按队列分配的,CookOrder一直在运行。然后你再次用比萨饼重复这个过程。

+0

我提高了这一点,但是......只是有一个线程安全集合并不能真正帮助我需要做的信号。 – 2011-04-11 17:55:15

1

看起来你需要的只是一个PizzaManager,它决定首先要做什么Pizza,然后将它们传递给DeliveryBoy供他们交付。然后,一旦DeliveryBoyDeliversPizza,然后他回报PizzaManager检索下一个Pizza订单。 PizzaManager负责与优化哪些订单的烹饪和交付优先级有关的所有数学。 DeliveryBoy将可能具有PizzaManager作为delegate