C# Singleton-构造函数内的任务无法启动/未异步启动
我有一点奇怪的问题,很难解释。我有一个singleton类,在构造函数中我必须运行一个任务来初始化一些组件/资源 我深入使用了C#中的2个singleton实现,在一种情况下一切正常,在另一种情况下——不是 下面提供了代码和一些注释。 主要的问题是,由于某种原因,在一种情况下,当我使用带有initialier和static constructor的static字段时,任务没有启动(classTest2) 我做了一些其他的测试,看起来执行2任务不是异步启动的,而是在等待时间后同步启动的 实施一。一切正常C# Singleton-构造函数内的任务无法启动/未异步启动,c#,multithreading,singleton,task,autoresetevent,C#,Multithreading,Singleton,Task,Autoresetevent,我有一点奇怪的问题,很难解释。我有一个singleton类,在构造函数中我必须运行一个任务来初始化一些组件/资源 我深入使用了C#中的2个singleton实现,在一种情况下一切正常,在另一种情况下——不是 下面提供了代码和一些注释。 主要的问题是,由于某种原因,在一种情况下,当我使用带有initialier和static constructor的static字段时,任务没有启动(classTest2) 我做了一些其他的测试,看起来执行2任务不是异步启动的,而是在等待时间后同步启动的 实施一。一
public sealed class Test1
{
private static Test1 instance = null;
private static readonly object padlock = new object();
private Test1()
{
using (AutoResetEvent startEvent = new AutoResetEvent(false))
{
new Task(() => TaskThread(startEvent)).Start();
if (!startEvent.WaitOne(1000))
{
throw new Exception("ERROR");
}
}
}
public int Result()
{
return 10;
}
private void TaskThread(AutoResetEvent startEvent)
{
//I am initializing some stuff here
startEvent.Set();
}
public static Test1 Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Test1();
}
return instance;
}
}
}
}
实现2,任务从未启动,或在事件等待时间之后启动
public sealed class Test2
{
private static readonly Test2 instance = new Test2();
static Test2()
{
}
private Test2()
{
using (AutoResetEvent startEvent = new AutoResetEvent(false))
{
new Task(() => TaskThread(startEvent)).Start();
//here it fails to wait successfully and throws an
//exception. Time limit is not reached
if (!startEvent.WaitOne(1000))
{
throw new Exception("ERROR");
}
}
}
public int Result()
{
return 20;
}
private void TaskThread(AutoResetEvent startEvent)
{
//I am initializing some stuff here as well
//but in this implementation code is never reached
startEvent.Set();
}
public static Test2 Instance
{
get
{
return instance;
}
}
}
我很好奇为什么会发生这种情况,以及今后如何避免这种问题。非常感谢 这种“奇怪”行为的根本原因很简单——CLR在锁下执行静态构造函数。这将阻止创建的线程进入
taskshread()
方法并将startEvent
设置为信号状态
在你面对这样一个问题和困惑几个小时之后,你开始理解为什么许多来源建议不要使用可疑的结构,比如静态构造函数,全局变量,等等。我想这可能是因为在静态字段初始化过程中,
System.TypeInitializer
造成的。@m.rogalski您能再解释一下吗?System.TypeInitializer
在静态初始化过程中初始化某些类时有问题。顺序是先初始化静态类型,然后初始化静态成员,再初始化调用入口点。可能在静态初始化期间,TypeInitializer
没有关于特定类型的信息?非常感谢!对于来到这里的其他人,这里有一些关于这个主题的附加信息,静态构造函数是毫无疑问的。正在静态构造函数中启动线程/任务。