简体   繁体   English

单例中的新线程从未结束

[英]New thread in singleton never finished

I have simple singleton class: 我有简单的单例课程:

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;
        }
    }
}

When I'm trying instatiate this by: 当我尝试通过以下方式将其隐瞒时:

var ir =  MySingleton.Instance.IsReady;

it never ends - the while loop is infinite. 它永远不会结束-while循环是无限的。 Why? 为什么? And how to run backround thread in singleton at constructor? 以及如何在构造函数的singleton中运行backround线程?

You're deadlocking. 你陷入僵局。 You're not allowed to call any methods from another thread before the static constructor is executed. 在执行静态构造函数之前,不允许从另一个线程调用任何方法。 Static constructor includes the static field initalizers too. 静态构造函数也包括静态字段初始化器。

Since you're blocking the calling thread with a while loop, static field initialization will not complete and the new thread will neither be permitted to execute MyAction either. 由于使用while循环阻塞了调用线程,因此静态字段初始化将不会完成,新线程也将不允许执行MyAction

Your code is almost identical to this code where Eric demonstrates the deadlock. 您的代码几乎是相同的代码埃里克演示了僵局。

And to quote eric's comment from same answer why does it deadlock: 并引用eric从相同答案中得出的评论为什么会死锁:

@Lieven: The static constructor must run no more than once and it must run before the first call to any static method in the class. @Lieven:静态构造函数必须运行不超过一次,并且必须在第一次调用类中的任何静态方法之前运行。 Main is a static method, so the main thread calls the static ctor. Main是静态方法,因此主线程调用静态ctor。 To ensure it only runs once, the CLR takes out a lock that is not released until the static ctor finishes. 为了确保它只能运行一次,CLR会取出一个锁,直到静态ctor完成后才会释放。 When the ctor starts a new thread, that thread also calls a static method, so the CLR tries to take the lock to see if it needs to run the ctor. 当ctor启动新线程时,该线程还会调用静态方法,因此CLR尝试获取该锁以查看是否需要运行ctor。 The main thread meanwhile "joins" the blocked thread, and now we have our deadlock. 同时,主线程“加入”了被阻塞的线程,现在我们陷入了僵局。 – Eric Lippert Jan 17 '12 at 14:28 –埃里克·利珀特(Eric Lippert)2012年1月17日14:28

To answer your question; 回答你的问题; Don't do that. 不要那样做 You gain nothing by starting a thread and waiting for it. 通过启动线程并等待它,您一无所获。 Just simply run the method synchronously. 只需简单地同步运行该方法即可。

This works. 这可行。 I am not a Singleton expert - if this violates any rules, someone please point it out. 我不是Singleton专家-如果这违反任何规则,请指出。 But this gets around the deadlock. 但这绕开了僵局。 I copied your code into a console app, if you're using it elsewhere, adjust appropriately. 我已将您的代码复制到控制台应用程序中,如果您在其他地方使用它,请进行适当调整。

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;
    }
}

Have a look at the lock statement when you create an instance of your singleton to make it thread safe. 创建单例实例使其线程安全时,请查看lock语句

An example of how to use it in the singleton pattern can be found here: http://www.dofactory.com/net/singleton-design-pattern 在单例模式中如何使用它的示例可以在以下位置找到: http : //www.dofactory.com/net/singleton-design-pattern

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

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