繁体   English   中英

单例中的新线程从未结束

[英]New thread in singleton never finished

我有简单的单例课程:

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循环是无限的。 为什么? 以及如何在构造函数的singleton中运行backround线程?

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

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

您的代码几乎是相同的代码埃里克演示了僵局。

并引用eric从相同答案中得出的评论为什么会死锁:

@Lieven:静态构造函数必须运行不超过一次,并且必须在第一次调用类中的任何静态方法之前运行。 Main是静态方法,因此主线程调用静态ctor。 为了确保它只能运行一次,CLR会取出一个锁,直到静态ctor完成后才会释放。 当ctor启动新线程时,该线程还会调用静态方法,因此CLR尝试获取该锁以查看是否需要运行ctor。 同时,主线程“加入”了被阻塞的线程,现在我们陷入了僵局。 –埃里克·利珀特(Eric Lippert)2012年1月17日14:28

回答你的问题; 不要那样做 通过启动线程并等待它,您一无所获。 只需简单地同步运行该方法即可。

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

namespace TestApp
{
class Program
{
    static void Main(string[] args)
    {
        while (!MySingleton.Instance.IsReady)
            Thread.Sleep(100);
        Console.WriteLine("Done");
        Console.Read();
    }
}

public class MySingleton
{
    static MySingleton()
    {
    }

    private static readonly MySingleton instance = new MySingleton();
    private static bool threadFinished = false;
    public bool IsReady
    {
        get { return threadFinished; }       
    }

    private MySingleton()
    {
        Thread t = new Thread(new ThreadStart(MyAction));

        t.Start();
    }

    public static MySingleton Instance
    {
        get { return instance; }
    }
    static void MyAction()
    {
        threadFinished = true;
    }
}

创建单例实例使其线程安全时,请查看lock语句

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM