C# C语言中的单例对象构造问题#

C# C语言中的单例对象构造问题#,c#,constructor,singleton,C#,Constructor,Singleton,下面是实现singleton类(双重检查锁定)的一段代码 这就是某些编译器优化的问题吗?请帮助您不需要单例,事实上您不需要单例。为什么现在人们要单身 看,这很简单: public sealed class Plugin { private static readonly Plugin _instance; private /*readonly?*/ Dictionary<int, string> myMap; private Plugin() {

下面是实现singleton类(双重检查锁定)的一段代码


这就是某些编译器优化的问题吗?请帮助

您不需要单例,事实上您不需要单例。为什么现在人们要单身

看,这很简单:

public sealed class Plugin
{
    private static readonly Plugin _instance;
    private /*readonly?*/ Dictionary<int, string> myMap;

    private Plugin()
    {
        myMap = MapInit(GetMainModuleName());
    }

    static Plugin()
    {
        _instance = new Plugin();
    }

    public static Plugin Instance
    {
        get
        {
            return _instance;
        }
    }
}

即使。。。只需使用静态构造函数。

好的,这里有一个实际的问题,听起来可能很幼稚。带有上述代码的dll已加载到主应用程序中,该应用程序的exe.config无效。由于我的dll有单独的dll.config(这是有效的),应用程序在通过调试器运行时工作正常,但在部署环境中运行时(未连接调试器),它遇到了无效的配置文件异常

我已经将主exe.config设置为有效的配置文件,现在可以使用了


因此,基本上,解决方案就像检查构建过程中是否存在异常一样幼稚。

这听起来不太可能——你到底是如何诊断的?既然有更简单、更不脆弱的替代方案,为什么还要使用DCL呢?(请参阅)我之所以使用DCL,是因为上面的单例类用于多线程环境。我通过在进程运行时附加到进程来诊断这个问题,这不是使用DCL的原因,而是使用任何简单的线程安全方法的原因。说你关注这个过程并不能告诉我们太多——你到底在观察什么?您是否添加了任何日志来显示发生了什么?不幸的是,没有此日志。但我可以加一个。我将解释我是如何诊断的,如果让应用程序自己运行,映射将不会初始化,因此映射中的项目计数为零,但是如果我一次调试一个步骤,映射将使用其中的一些项目初始化。我还能做些什么来更准确地诊断问题呢?测井将是第一步。这里有许多相关的解释,包括初始化本身中的竞争条件。如果你能制作一个简短但完整的程序来演示这个问题,那将很有帮助。感谢你的宝贵建议,我将仔细检查我代码中的缺陷。这是一个巨大的挑战<代码>密封类插件{private Plugin(){}公共静态只读插件实例=新插件();}。在第一次使用该类之前未实例化,没有锁,因此没有线程同步问题,易于理解/维护。@Basic是的,我以前写过这段代码。虽然我会做一个财产。。。我们仍然同意避免单例,并且静态构造函数比单例更好(无论该构造函数是否隐式)。
myMap = MapInit(GetMainModuleName());
public sealed class Plugin
{
    private static readonly Plugin _instance;
    private /*readonly?*/ Dictionary<int, string> myMap;

    private Plugin()
    {
        myMap = MapInit(GetMainModuleName());
    }

    static Plugin()
    {
        _instance = new Plugin();
    }

    public static Plugin Instance
    {
        get
        {
            return _instance;
        }
    }
}
public sealed class Plugin
{
    private static readonly Plugin _instance;
    private static int _initializing;
    private static ManualReserEvent _done;
    private Dictionary<int, string> myMap;

    private Plugin()
    {
        myMap = MapInit(GetMainModuleName());
    }

    static Plugin()
    {
        _done = new ManualResetEvent(false);
    }

    public static Plugin Instance
    {
        get
        {
            if (Interlocked.CompareExchance(ref _initializing, 1, 0) == 0)
            {
                _instance = new Plugin();
                _done.Set();
            }
            else
            {
                _done.WaitOne();
            }
            return _instance;
        }
    }
}