簡體   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