2010-01-25 636 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的意义在于,稍后在函数中有对该对象的引用,所以它不会被丢弃。该框架不够聪明,知道你的循环永远不会退出,所以它永远不会处理该对象。