单例实现在32位但不是64位上工作正常

时间:2010-02-02 19:42:42

标签: c# multithreading 64-bit singleton

我正在使用通过单例访问的共享对象的应用程序。它在32位上运行良好,但在64位上它似乎没有正确锁定。在我的对象的构造函数中,我有代码检查一些配置reg键并提示用户它们是否不存在。在32位我看到提示只有一次如预期,但在64位上提示被多次显示。我的代码如下:

    private static readonly object padlock = new object();
    private static MyClass _instance = null;
    public static MyClass Instance
    {
        get
        {

            lock (padlock)
            {
                if (_instance == null)
                {
                    _instance = new MyClass();
                }
            }
            return _instance;
        }
    }

非常感谢任何输入。

已修改要包含样本使用情况:

    public OtherObject()
    {
        InitializeComponent();

        MyClass.Instance.OtherObjectOrSomething = this;

        this.Load += new System.EventHandler<EventArgs>(OtherObject_Load);
    }

再次编辑 这是在Office AddIn内部运行的。因此,位数由办公室的安装决定。我定义了一个私有的无参数构造函数。

由于

删除了稍微不确定的构造函数

6 个答案:

答案 0 :(得分:2)

它可能是构造函数中代码内部导致多个提示的内容。注册表的视图将不同于32位进程与64位进程,因此它们可以响应不同的外部条件

答案 1 :(得分:0)

修改 基于一些答案和评论,我将回到原来的答案。

我也是这样做的,除非我将readonly更改为volatile。

private static volatile object padlock = new object();

volatile关键字让编译器知道不优化指令,这将确保字段中存在最新的值。

答案 2 :(得分:0)

有关各种单例实现模式问题的精彩讨论,请参阅http://www.yoda.arachsys.com/csharp/singleton.html(来自Jon Skeet)。

正如它所写,你遇到的最大问题是编译器提供了一个默认的无参数构造函数,它将是公共的。你应该明确地创建一个私有的conpsterless contstructor来防止这种情况。我没有看到任何基于平台架构的问题。

以下是我通常使用的代码(在32位和64位系统上):

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new object();

   private Singleton()
   {
      // any code that needs to run to create a valid instance of the object.
   }

   public static Singleton Instance
   {
      get
      {
         if (instance == null)
         {
            lock(syncRoot)
            {
               if (instance == null)
               {
                  instance = new Singleton();
               }
            }
         }

         return instance;
      }
   }
}

答案 3 :(得分:0)

我将实施here放在一起,但出于某种原因,它被投了两次:(

答案 4 :(得分:0)

您的单身人士会将您限制为每个应用程序域一个实例。是否有机会在多个应用程序域中创建倍数?你可以考虑一下。

答案 5 :(得分:0)

  

在我的对象的构造函数中,我有代码检查一些配置注册密钥,提示用户是否不存在。

在一个延迟加载的静态实例中,这是一件相当危险的事情。你能保证UI线程始终是第一个使用这个代码路径吗?我不确定这是你问题的一部分,但是在线程安全代码中与UI交互很少是一个好主意,并且我已经看到各种奇怪的事情在不同的环境中发生了。< / p>

您可以在延迟加载之外移动此UI代码吗?如果这是一个Office加载项,那么你应该有一个Startup事件来挂钩,保证只执行一次。您甚至不需要锁定代码,您可以确保在任何其他线程尝试触摸它之前初始化它。