2010-07-25 36 views
1

我想知道編寫應用程序的最佳方式是什麼。基本上,我有一個多線程運動模擬項目,可以同時執行不同的遊戲模擬。編程一個長時間運行的基於時間的過程

我將我的匹配存儲在附有DateTime的SQLite數據庫中。

我想編寫一個應用程序,每隔一小時左右檢查一次是否需要播放任何新匹配併產生這些線程。

我不能依靠任務計劃程序每小時執行一次,因爲存在該進程的不同實例將共享的對象(特別是比賽對象),我懷疑在保存時會被新的進程覆蓋回到DB中。所以理想情況下,我需要編寫一些長時間睡眠的過程,可以在幾個小時之內休息。

我寫過我的對象模型,以便每個對象只從內存中加載一次,所以只要所有的仿真線程都從這個應用程序派生出來,它們就不應該覆蓋數據。

編輯:上要求

更多細節基本上,多個匹配需要能夠同時運行。這些匹配可以是任意長度的,所以不需要一個在另一個開始之前完成(事實上,在大多數情況下,會有多個匹配在同一時間執行)。

我想象的是一個在後臺運行(我猜是服務)的程序,它睡了60分鐘,然後檢查數據庫以查看是否應該啓動任何遊戲。如果有任何要開始,它會啓動線程來模擬這些遊戲,然後重新進入睡眠狀態。因此,仿真線程正在運行,但「調度」線程又睡了60分鐘。

我不能(我認爲)使用默認的操作系統任務調度接口的原因是,這些需要執行的任務被剔除爲一個新的進程。我已經開發了我的數據庫對象模型,使得它們在第一次加載(內存引用)時被每個對象類緩存,這意味着每個對象只從內存加載一次,並且所有的保存都使用該引用。這意味着當每個仿真線程完成並保存其狀態時,將使用相同的參考(更新狀態)來保存狀態。如果每次啓動一個不同的可執行文件,大概每個進程都會打開一個不同的內存引用,因此一個進程可以保存到數據塊中並覆蓋另一個進程寫入的狀態。

服務看起來像要走的路。有沒有辦法讓服務剛好睡60分鐘,然後喚醒並執行一個函數?我覺得這是一個標準的控制檯應用程序會浪費內存,但我不知道是否有一種有效的方式來做到這一點,我不知道。

+0

Linux?使用cron。不是Linux?在...處使用。內置作業功能有什麼問題? – 2010-07-25 22:13:19

+0

你讀過這個問題了嗎?如果可執行文件不止一次啓動,那麼當數據保存回數據庫時,數據將被稍後的過程覆蓋...即,一個匹配的結果將被保存在DB中的聯賽信息中覆蓋。 – sohum 2010-07-25 22:24:05

+0

它是Windows,順便說一句。 – sohum 2010-07-25 22:34:13

回答

2

如果您想使它真的可靠,請將其設爲服務。

但我沒有看到任何問題,使其成爲一個正常的(控制檯,WinForms,WPF)應用程序。

也許你可以擴大一點的要求。

+0

我在想服務可能是理想的,但我從來沒有寫過一個,所以我不知道如果這是設計的理想選擇。 我將詳細討論問題中的要求。 – sohum 2010-07-26 00:04:20

+0

服務中很少有「魔術」。這意味着SCM可以在啓動時自動啓動,如果失敗則重新啓動。 – kyoryu 2010-07-26 00:12:57

+0

我剛剛創建了一個正常的控制檯應用程序,它可以連續運行並在每次循環完成時休眠60分鐘。我想沒有更有效的方法來實現這一點! – sohum 2010-07-26 03:39:03

0

我不能(我認爲)使用默認的操作系統任務調度接口的原因是,這些需要執行的任務被剔除爲一個新的進程。我已經開發了我的數據庫對象模型,使得他們被第一次加載(內存引用)的每個對象類的緩存意味着每個對象只能從內存中加載一次,即基準對所有使用節省

如果您要讓所有東西永遠保持緩存,那麼你需要有一個永遠運行的應用程序。您可以將其設置爲Windows服務或正常的Windows應用程序。
Windows服務只是一個符合服務管理器API的普通exe。如果你想製作一個,Visual Studio有一個嚮導,可以爲你自動生成一些框架代碼。基本上,而不是有一個Main方法你有Service類與Run方法和其他一切都是相同的。

如果您想要,可以使用Windows任務計劃程序來安排您的操作。你這樣做的方式是讓你的長時間運行的Windows服務在不做任何事的背景中。讓它打開一個TCP套接字或命名管道或什麼的,只是坐在那裏。然後寫一個小的「存根」exe文件,它只是連接到這個套接字或命名管道,並告訴後臺應用程序喚醒。
這當然比在後臺應用程序中做sleep困難得多,但它確實讓您擁有更多的控制權 - 您可以在不重新啓動後臺服務的情況下更改睡眠時間,按需運行它,等等


然而,我會考慮你的設計。您依賴長期服務的事實是一個很大的失敗點。如果你的應用需要運行幾天,並且你有一個崩潰的bug,那麼你必須重新開始。一個更好的體系結構是遵循Unix模型,在這個模型中,你有一些小的進程開始,做一件事,然後完成(在這種情況下,處理每個遊戲模擬,因爲它是自己的進程,所以如果一個人死了,它不需要主進程或其他模擬下來)。

這似乎是你試圖讓它長期運行的主要原因是緩存你的數據庫查詢。你真的需要這樣做嗎?很多時間數據庫足夠快(他們有自己的緩存,這是非常聰明的)。我見過程序員犯的一個常見錯誤就是假設像數據庫這樣的東西速度很慢,並且浪費了一堆時間來進行優化,但實際上它可能會很好