2010-01-25 60 views
3

我目前正在C#中的一個應用程序,該應用程序在其他方法調用的每次迭代之後在Thread.Sleep調用的無限循環上運行。我主要是 -如何實現一個無限循環的單例模式 - C#

static void Main(string[] args) 
    { 
     bool isOnlyInstance = false; 
     Mutex mutex = new Mutex(true, "RiskMetricsSensitivitiesDatabaseLoader", out isOnlyInstance); 

     if (!isOnlyInstance) 
     { 
      return; 
     } 

     while (true) 
     { 
      ProcessData(); 
      Thread.Sleep(MainLoopSleep); 
     } 

     GC.KeepAlive(mutex); 
    } 

我已經插在方法結束時保持活動的呼叫,保證單互斥按預期工作,通過各種網站的概述。對KeepAlive的調用應該保持垃圾收集不會拋出互斥量,因爲.NET期待着預測/優化垃圾收集。

我的問題是,由於實際調用KeepAlive永遠不會到達,我應該把它放在Thread.Sleep之後的循環中嗎?編譯器警告KeepAlive永遠不會被調用,我擔心它會忽略垃圾回收預防算法中的這一行。

+1

把它放在一個finally塊中,如果你如此擔心。當然,它不應該有所作爲,因爲循環是無限的 - 它只會在程序關閉之前調用「KeepAlive()」... – 2010-01-25 18:54:53

+0

什麼網站?這味道不好。 – jason 2010-01-25 18:54:57

+0

我不明白爲什麼GC應該收集你的互斥體,如果你仍然持有對它的引用(就像它似乎)。你能提供一些鏈接到提到這個問題的網站嗎? – LorenzCK 2010-01-25 19:02:53

回答

10

Mutex是一次性的。爲什麼不把它包裝在using

using(new Mutex(blah, blah, blah)){ 
    while(true){ 
     Blah(blah); 
    } 
} 

請注意,這種方法甚至無需將新的Mutex分配給指定的變量。

+0

+1。很好的解決方案,你甚至會提到使用靜態變量的替代方法。 – RichardOD 2010-01-25 18:57:11

+0

@RichardOD:使用靜態變量是一種選擇。不過,我沒有提到它。 – 2010-01-25 18:59:37

+0

快速蜘蛛俠,使用你的常識!我的意思是,感謝這個好主意。 – 2010-01-25 19:08:11

1

你應該沒問題。 GC.KeepAlive的意義在於,稍後在函數中有對該對象的引用,所以它不會被丟棄。該框架不夠聰明,知道你的循環永遠不會退出,所以它永遠不會處理該對象。