2013-03-12 37 views
7

我遇到這樣的代碼:Windows服務實現IDisposable - 這是不好的做法嗎?

public class ServiceLauncher2 : ServiceBase, IDisposable 

然後將此:

 /// <summary> 
     /// Disposes the controllers 
     /// </summary> 
     // This is declared new as opposed to override because the base class has to be able to 
     // call its own Dispose(bool) method and not this one. We could just as easily name 
     // this method something different, but keeping it Dispose is just as valid. 
     public new void Dispose() 
     { 
      foreach (var mgr in _threadManagers) 
       mgr.Dispose(); 
      base.Dispose(); 
     } 

我從來沒有在Windows服務實施前看到了這一點。通常只是OnStop/OnStart被覆蓋。這是不好的做法嗎?

回答

11

讓我們算方式,這是不好的做法:

  • 關鍵字光柵,它告訴編譯器閉嘴代碼中的一個潛在的問題。一個真實的代碼,使用這個類的代碼可以很容易地結束調用ServiceBase.Dispose()。 ServiceBase實現一次性模式,正確的方法是覆蓋受保護的Dispose(bool)方法

  • Dispose()方法會在後面留下一個_threadManagers集合對象,其中只包含死對象。這也使得這個系列作爲一個小門而死,之後重複它也沒有意義。它應該已被清空

  • 可以調用此Dispose()方法的唯一時間是在服務終止時。無法在OnStop()中執行它,它也處置了ServiceBase。在終結器運行並且進程終止之前,將「控制器」放置一微秒是沒有意義的。 Dispose()應該只用於允許非託管資源儘早解除分配。當過程停止一毫秒後,沒有早期的

這段代碼沒有意義。不要使用它。

3

它看起來不標準,但it is legit。所以我不一定稱之爲不好的做法,雖然它引入了混淆的事實使得它不好實踐?

這是僅作爲服務運行還是存在控制檯模式? (控制檯應用程序不會調用OnStop。)或者是否有其他(自定義)方式來停止此服務過程?

從我自己的早期問題Ammending:

我不知道爲什麼new代替override,特別是因爲 base.Dispose()被調用。

原因:

'SomeClass.Dispose()':不能重寫繼承構件 'System.ComponentModel.Component.Dispose()',因爲它未標記 虛擬的,抽象的,或覆蓋

換句話說,ServiceBase.Dispose的實現是不可覆蓋的。

+0

它是一種服務應用程序,但爲了調試的目的有一小段代碼通過控制檯(interative)運行它,但部署時它是一項服務。 – 2013-03-12 19:29:42

+0

好的,所以對於控制檯模式的緣故,我會離開Dispose方法,因爲OnStop不會被調用。 – 2013-03-12 19:37:58

+0

對於ServiceBase來說,當整個進程終止時調用一個析構函數並不重要,因此無論如何它的所有非託管資源都將被釋放。這並不是說我們正在處理一個多次實例化和銷燬的庫類,從而導致內存泄漏和資源耗盡。 – ajeh 2017-10-03 15:13:47

0

只需添加到由漢斯·保羅已經完美的答案:聲明ServiceLauncher2IDisposable是多餘的,因爲ServiceBaseComponent這又是已經IDisposable

相關問題