Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Singleton-构造函数内的任务无法启动/未异步启动_C#_Multithreading_Singleton_Task_Autoresetevent - Fatal编程技术网

C# Singleton-构造函数内的任务无法启动/未异步启动

C# Singleton-构造函数内的任务无法启动/未异步启动,c#,multithreading,singleton,task,autoresetevent,C#,Multithreading,Singleton,Task,Autoresetevent,我有一点奇怪的问题,很难解释。我有一个singleton类,在构造函数中我必须运行一个任务来初始化一些组件/资源 我深入使用了C#中的2个singleton实现,在一种情况下一切正常,在另一种情况下——不是 下面提供了代码和一些注释。 主要的问题是,由于某种原因,在一种情况下,当我使用带有initialier和static constructor的static字段时,任务没有启动(classTest2) 我做了一些其他的测试,看起来执行2任务不是异步启动的,而是在等待时间后同步启动的 实施一。一

我有一点奇怪的问题,很难解释。我有一个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
没有关于特定类型的信息?非常感谢!对于来到这里的其他人,这里有一些关于这个主题的附加信息,静态构造函数是毫无疑问的。正在静态构造函数中启动线程/任务。