单例中的新线程从未完成

本文关键字:未完成 线程 新线程 单例中 | 更新日期: 2023-09-27 18:32:32

我有一个简单的单例类:

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

单例中的新线程从未完成

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

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

您的代码几乎与 Eric 演示死锁的此代码相同。

并引用同一个答案中的 eric 评论,为什么它会陷入僵局:

@Lieven:静态构造函数必须运行不超过一次,并且 必须在首次调用类中的任何静态方法之前运行。主要 是一个静态方法,因此主线程调用静态 CTOR。自 确保它只运行一次,CLR 取出一个不是 释放,直到静态 CTOR 完成。当 ctor 开始新的 线程,该线程还调用静态方法,因此 CLR 尝试 拿锁看看它是否需要运行CTOR。主线程 同时"加入"被阻塞的线程,现在我们陷入了僵局。– 埃里克·利珀特 1月 17 '12 在 14:28

回答您的问题;别这样。通过启动一个线程并等待它,你一无所获。只需同步运行该方法即可。

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

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