单身的新线程从未完成

时间:2016-01-29 19:40:32

标签: c# multithreading

我有简单的单身人士课程:

namespace TestApp
{
    public class MySingleton
    {
        static MySingleton()
        {
        }

        private static readonly MySingleton instance = new MySingleton();
        private  bool threadFinished = false;
        public bool IsReady = false;

        private MySingleton()
        {
            Thread t = new Thread(MyAction);
            t.Start();

            while (!threadFinished)
               Thread.Sleep(10);
        }

        public static MySingleton Instance
        {
            get { return instance; }
        }

        private void MyAction()
        {
            threadFinished = true;
        }
    }
}

当我尝试通过以下方式实现这一目标时:

var ir =  MySingleton.Instance.IsReady;

它永远不会结束 - while循环是无限的。为什么?以及如何在构造函数中以单例形式运行backround线程?

3 个答案:

答案 0 :(得分:2)

你陷入僵局。在执行静态构造函数之前,不允许从另一个线程调用任何方法。静态构造函数也包括静态字段初始化器。

由于您使用while循环阻塞调用线程,因此静态字段初始化将无法完成,并且新线程也不会被允许执行MyAction

您的代码几乎与this code相同,其中Eric演示了死锁。

并引用埃里克的同一回答的评论为什么会陷入僵局:

  

@Lieven:静态构造函数必须运行不超过一次   必须在第一次调用类中的任何静态方法之前运行。主要   是一个静态方法,所以主线程调用静态ctor。至   确保它只运行一次,CLR取出一个没有的锁   释放,直到静态ctor完成。当ctor开始一个新的   线程,该线程也调用静态方法,因此CLR尝试   拿锁看看它是否需要运行ctor。主线程   同时“加入”被阻止的线程,现在我们陷入僵局。 -   Eric Lippert 12年1月17日14:28

回答你的问题;不要那样做。通过启动一个线程并等待它你什么也得不到。只需简单地同步运行该方法。

答案 1 :(得分:1)

这很有效。我不是Singleton专家 - 如果违反任何规则,请有人指出。但这解决了僵局。我将您的代码复制到控制台应用程序中,如果您在其他地方使用它,请进行适当调整。

System.Net

答案 2 :(得分:0)

在创建单例实例时,请查看lock statement以确保其线程安全。

如何在单例模式中使用它的示例可以在这里找到:http://www.dofactory.com/net/singleton-design-pattern