我有简单的单身人士课程:
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循环是无限的。为什么?以及如何在构造函数中以单例形式运行backround线程?
答案 0 :(得分:2)
你陷入僵局。在执行静态构造函数之前,不允许从另一个线程调用任何方法。静态构造函数也包括静态字段初始化器。
由于您使用while循环阻塞调用线程,因此静态字段初始化将无法完成,并且新线程也不会被允许执行MyAction
。
您的代码几乎与this code相同,其中Eric演示了死锁。
并引用埃里克的同一回答的评论为什么会陷入僵局:
@Lieven:静态构造函数必须运行不超过一次 必须在第一次调用类中的任何静态方法之前运行。主要 是一个静态方法,所以主线程调用静态ctor。至 确保它只运行一次,CLR取出一个没有的锁 释放,直到静态ctor完成。当ctor开始一个新的 线程,该线程也调用静态方法,因此CLR尝试 拿锁看看它是否需要运行ctor。主线程 同时“加入”被阻止的线程,现在我们陷入僵局。 - Eric Lippert 12年1月17日14:28
回答你的问题;不要那样做。通过启动一个线程并等待它你什么也得不到。只需简单地同步运行该方法。
答案 1 :(得分:1)
这很有效。我不是Singleton专家 - 如果违反任何规则,请有人指出。但这解决了僵局。我将您的代码复制到控制台应用程序中,如果您在其他地方使用它,请进行适当调整。
System.Net
答案 2 :(得分:0)
在创建单例实例时,请查看lock statement以确保其线程安全。
如何在单例模式中使用它的示例可以在这里找到:http://www.dofactory.com/net/singleton-design-pattern