2011-04-11 112 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