[英]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.