2009-09-17 66 views
1

我最近接管了一箇舊的Windows服務,它已被寫入系統事件日誌以下事件:窗口服務和C#設計模式的問題

事件ID:7034
說明: 爲MyService服務意外終止了 。它完成了這個X 時間(s)。

我一直在尋找了源代碼,發現在服務類庫下面的代碼模式: (它已被簡化爲保護無辜者。)

public static void StartService() 
{ 
    //do some stuff... 
    ManageCycle(); 
} 

public static void ManageCycle() 
{ 
    //do some stuff 
    ManageCycle(); 
} 

所謂這個編碼彭定康並可能導致Windows服務關閉(即內存泄漏)?

+1

OH-MY-GOD !!!爲什麼使用遞歸調用而不是while循環?! – 2009-09-17 20:25:39

+12

投票結束爲「屬於thedailywtf.com」 – 2009-09-17 20:28:27

回答

1

這是一個遞歸調用,最終會打擊堆棧。

+1

......除非它有我們沒有看到的有條件退出。 – 2009-09-17 20:27:32

+0

代碼中沒有條件退出。 – 2009-09-17 20:59:04

+0

@邁克爾:沒關係,這不是一個遞歸調用技術的地方。 – 2009-09-20 18:58:35

3

它假設拋出StackOverflow(HA HA :))異常,因爲無盡的遞歸調用。

看看this example - 您應該選擇適合您的架構的技術。

0

這是一個遞歸調用,顯然沒有退出條件。最終由於致電ManageCycle永遠不會返回,它將用完堆棧。

另外,StartService方法永遠不會返回,它應該至少將一個前景線程串起來然後返回。

0

遞歸,它像遞歸調用自己一樣。我很驚訝沒有堆棧溢出異常。運行此服務器的機器上的服務屬性可能配置爲在發生故障時重新啓動服務。

3

這看起來像堆棧溢出異常模式。伊蘭是對的。使用while循環:

 
public static void StartService() 
{ 
    //do some stuff... 
    isRunning = true; 
    ManageCycle(); 
} 

public static void ManageCycle() 
{ 
    while(isRunning) 
    { 
    //do some stuff and wrap in exception handling 
    } 
} 

public static void StopService() 
{ 
    isRunning=false; 
} 
0

它是遞歸的好吧。它會不斷地重複調用自己(一件壞事),並且會導致一個堆棧溢出。

「//做些什麼」做什麼?也許有一個很好的理由,它自己調用, b但是沒有辦法擺脫循環(遞歸),應用程序將退出。

+0

//做一些東西一塊服務調用數據庫來檢索監視器的集合,以檢查網頁的健康狀況,Windows服務,硬盤驅動器容量以及是否可以ping通設備。 – 2009-09-17 21:21:02

1

這種情況的最佳答案: 除非您的算法具有遞歸結構,否則不要使用遞歸算法。例如,如果你正在分析文件系統,並希望掃描特定的目錄,你會想要做的事,如:

void ScanDirectory(Directory) 
{ 
    // Handle Files 
    if (currfile.directory) 
     ScanDirectory(currfile) 
} 

這是有道理的,因爲它比反覆做要容易得多。但除此之外,當你只是一遍又一遍地重複一個動作時,使其成爲遞歸是完全沒有必要的,並且會導致代碼效率低下並最終導致堆棧溢出。

+0

+1這是這個問題的正確結論。這更像是「如何正確編碼?」問題比「如何實現代碼完美?」題。 – 2009-09-18 12:42:20