如何用无限循环实现单例模式-C#

如何用无限循环实现单例模式-C#,c#,garbage-collection,singleton,mutex,C#,Garbage Collection,Singleton,Mutex,我目前正在使用C#开发一个应用程序,它在一个无限循环上运行,在其他方法调用的每次迭代后都会调用Thread.Sleep。我的主要意见是—— static void Main(string[] args) { bool isOnlyInstance = false; Mutex mutex = new Mutex(true, "RiskMetricsSensitivitiesDatabaseLoader", out isOnlyInstance);

我目前正在使用C#开发一个应用程序,它在一个无限循环上运行,在其他方法调用的每次迭代后都会调用Thread.Sleep。我的主要意见是——

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调用,以确保单例互斥按预期工作,正如各种网站所概述的那样。调用KeepAlive应该可以防止垃圾收集丢弃互斥锁,因为.NET期待预测/优化垃圾收集


我的问题是,由于KeepAlive的实际调用从未到达,我是否应该在Thread.Sleep之后将其放入循环中?编译器警告说KeepAlive永远不会被调用,我担心它会因此在我的垃圾收集预防算法中忽略这一行

Mutex
是一次性的。为什么不使用将其包装在

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

请注意,这甚至不需要将新的
互斥对象
分配给命名变量。

您应该没问题。GC.KeepAlive的要点就是在函数的后面有一个对对象的引用,所以它永远不会被释放。框架不够聪明,无法知道循环永远不会退出,因此它永远不会处理对象。

如果您如此担心,请将其放入finally块中。当然,这不应该有什么区别,因为循环是无限的——它只会在程序关闭之前调用“KeepAlive()”……什么网站?这很难闻。我不明白为什么GC应该收集你的互斥锁,如果你仍然持有对它的引用(看起来)。你能提供一些指向提到这个问题的网站的链接吗?@Lck:如果没有
GC.KeepAlive(mutex)
或其他互斥对象的使用,GC可以随时收集互斥对象(并最终确定它)。在方法中引用的最后一次使用之后,该方法不再可以访问该对象,因此,除非对该对象进行任何其他可访问的引用,否则该对象符合收集条件。这就是GC.KeepAlive()方法的目的。@P爸爸:谢谢。我从来没有意识到.NET垃圾收集器有这么大的攻击性。+1。很好的解决方案,你甚至提到了使用静态变量的替代方法。@RichardOD:使用静态变量是一种替代方法。不过我没提。快蜘蛛侠,用你的常识!我的意思是,谢谢你的好主意。@P爸爸。你说得对。不知何故,我误读了“甚至没有将新互斥体分配给命名变量”。