有人能告诉我下面的代码有什么问题吗?理想情况下,它应该先启动一个线程,然后等待set事件。相反,它不会启动线程,只会卡在WaitOne()上。
我很想知道这条线是怎么回事,为什么?
class Program
{
static void Main(string[] args)
{
Testing t = Testing.Instance;
Console.Read();
}
}
class Testing
{
private static AutoResetEvent evt = new AutoResetEvent(false);
public static Testing Instance = new Testing();
private Testing()
{
Create();
evt.WaitOne();
Console.WriteLine("out");
}
private void Create()
{
Console.WriteLine("Starting thread");
new Thread(Print).Start();
}
private void Print()
{
Console.WriteLine("started");
evt.Set();
}
}编辑:到目前为止,@BrokenGlass提供的描述是有意义的。但是,将代码更改为下面的代码允许另一个线程访问实例方法,而不需要完成构造函数(由@NicoSchertler建议)。
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}发布于 2012-05-24 17:28:14
我怀疑这种行为的根本原因是,在构造函数完成执行之前,派生的线程无法访问Print方法--但构造函数从未完成执行,因为它正在等待仅从Print方法触发的信号。
用长evt.WaitOne()调用替换Thread.Sleep()确认了相同的行为--构造函数必须在对象的任何实例方法从另一个线程执行之前完成运行。
发布于 2012-05-24 17:41:15
问题是第二个线程创建得太早了。我不知道为什么,但是当在主程序启动之前启动时,它将不会执行。
您应该在其原始版本中使用单例模式。这会管用的。
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}此外,不应使evt变量保持静态。在大多数情况下,实例变量应该是单例类的唯一静态成员。
发布于 2012-05-24 17:30:17
我的猜测是静态字段初始化的相对时间问题。尝试在evt的构造函数中初始化Testing:
private static AutoResetEvent evt;
public static Testing Instance = new Testing();
private Testing()
{
evt = new AutoResetEvent(false);
Create();
evt.WaitOne();
Console.WriteLine("out");
}我应该注意到,这只是一个猜测--我原以为这段代码会正常工作。
https://stackoverflow.com/questions/10742363
复制相似问题