C # ASP .NET MVC 3 синглтон конструктор вызывается дважды - PullRequest
2 голосов
/ 15 февраля 2012

У меня есть проект, состоящий из трех проектов,

  1. Служба WCF
  2. Приложение Asp.net MVC 3
  3. Библиотека классов.

В библиотеке классов есть мой синглтон, который я сделал так:

public sealed class Singleton
{
    public static Singleton Instance { get; set; }

    private Singleton()
    {

    }

    public static Singleton Instance
    {
        get
        {
            if (Instance == null)
                Instance = new Singleton();
            return Instance;
        }
    }       
}

Дело в том, что я положил Debug.WriteLine в конструктор, и он вызывается дважды.
Я пытаюсь использовать синглтон из приложения mvc 3 и из службы WCF, но они делают разные экземпляры. Почему?

РЕДАКТИРОВАТЬ: я пробовал Treadsafe синглтон ранее. Это не имело никакого значения.

Ответы [ 6 ]

3 голосов
/ 15 февраля 2012

Здесь может происходить несколько вещей.

Скорее всего, ваше MVC-приложение и служба WCF работают в разных доменах приложений.В этом случае код не сможет «совместно использовать» один и тот же экземпляр.

Альтернативная и менее вероятная причина заключается в том, что, поскольку ваш код не является потокобезопасным, создается несколько экземпляров.Если конструктору Singleton требуется много времени для возврата, это может быть проблемой.Поскольку вы используете MVC3, я предполагаю .Net 4, и в этом случае Ленивый класс - ваш друг:

private static readonly Lazy<Singleton> _singleton = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return _singleton.Value; } }
1 голос
/ 15 февраля 2012

Полагаю, ваша реализация не является поточно-ориентированной. проверьте статью: Реализация Singleton в C #

вот пример, ориентированный на многопотоковое исполнение: (есть много других способов сделать это, более сложное и безопасное, это просто справка ...)

using System;

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

   private Singleton() {}

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

         return instance;
      }
   }
}
0 голосов
/ 15 февраля 2012

Вы можете использовать ленивый шаблон в .Net 4.0

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
} 

Источник: http://csharpindepth.com/Articles/General/Singleton.aspx

0 голосов
/ 15 февраля 2012

Во-первых, ваш точный код, как опубликовано, не работает.Это не является синтаксически правильным (фигурные скобки не сбалансированы), и есть два открытых члена Singleton.Instance.Я предполагаю, что ваш оригинальный код был таким:

public sealed class Singleton
{
    private static Singleton _instance { get; set; }

    private Singleton()
    {

    }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                Instance = new Singleton();
            return _instance;
        }
    }       
}

Проблема, вероятно, связана с многопоточностью.То есть, пока один из потоков вызывает new Singleton(), другой пытался получить Singleton.Instance, который, в свою очередь, вызывал другой new Singleton().

Вам следует либо использовать там двойную проверку блокировки:

public sealed class Singleton
{
    private static Singleton _instance { get; set; }

    private Singleton()
    {

    }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                lock (typeof(Singleton))
                    if (_instance == null)
                    {
                        var instance = new Singleton();
                        _instance = instance;
                    }
            return _instance;
        }
    }       
}

или, что намного проще,

public sealed class Singleton
{
    public static readonly Singleton _instance = new Singleton();

    private Singleton()
    {

    }
}
0 голосов
/ 15 февраля 2012

Если служба WCF работает как отдельное приложение, у нее будет собственный экземпляр синглтона, так как два приложения не разделяют память.

Служба WCF работает с IP-адресом / номером порта, отличным от приложения MVC?

0 голосов
/ 15 февраля 2012

У меня нет опыта работы с WCF, но, возможно, вам следует реализовать синглтон, безопасный для потоков, см .: http://www.yoda.arachsys.com/csharp/singleton.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...