C # Много экземпляров объекта Singleton - PullRequest
10 голосов
/ 05 декабря 2011

У меня проблема с шаблоном Singleton.

Это действительно странно, но похоже, что есть два или три экземпляра моего синглтон-паттерна. Мой веб-сайт - это сайт действий с таймерами, и я управляю этими таймерами и ценами с помощью моего объекта Singleton.

Что происходит, так это то, что некоторые люди видят некоторые цены, а другие видят другие цены всегда, когда они находятся в разных сетях.

Например, в моем офисе мои люди видят аукцион по цене 0,56 цента, все видят то же самое, но в другой сети, например, у меня дома, я вижу 0,55 цента, а таймеры тоже имеют разные значения.

Сказав это, я протестировал свой Singleton, сгенерировав GUID и записав его в свой лог-файл. Вот код

public class Singleton
{
    private static Singleton instance;
    private static System.Threading.Mutex mutex;

    System.Guid token;

    private Singleton() { 
        token = System.Guid.NewGuid();
        Logger.Log("New singleton Instance" + token.toString());
    }
    static Singleton()
    {
        instance = new Singleton();
        mutex = new System.Threading.Mutex();
    }

    public static Singleton Acquire()
    {
        mutex.WaitOne();
        return instance;
    }

    // Each call to Acquire() requires a call to Release()
    public static void Release()
    {
        mutex.ReleaseMutex();
    }

    public void SomeAction()
    {
       Logger.Log(token.toString() + " - SomeAction");
    }
}

В этом коде я генерирую маркер на конструкторе и регистрирую создание нового Singleton, затем ... в методе SomeAction я записываю, кто выполняет это действие.

После этого мы сделали пару тестов и загрузили файл журнала.

К моему удивлению, я вижу только один "Новый экземпляр Синглтона", который является правильным. но потом много вызовов метода SomeAction с разными GUID, что странно.

Я проверил, что объект создается только в статическом конструкторе, и я также проверил, что ручного создания нет нигде.

Для получения дополнительной информации это происходит только на моем рабочем сервере, который является хостингом goDaddy. Я спросил, существует ли более одного пула приложений для моего сайта, и они сказали, что существует только один пул приложений.

Ответы [ 5 ]

4 голосов
/ 05 декабря 2011

Ваше время жизни в одиночном цикле связано с текущим рабочим процессом IIS.

Если настроено несколько рабочих процессов, тогда не все запросы обрабатываются одним и тем же процессом и, следовательно, не одним и тем же синглтоном.

2 голосов
/ 05 декабря 2011

Не могу с уверенностью сказать, что это ваша проблема, но, возможно, стоит проверить:

  • Если вы создаете экземпляр до инициализации вашей структуры ведения журнала, кэшируется ли сообщение,или просто выбросить?Я видел, как сообщения журнала пропадали в прошлом, потому что они происходят до инициализации ведения журнала.
  • Возможно ли, что вы ссылаетесь на несколько версий сборки, содержащей этот класс?Это может привести к созданию одного экземпляра класса для каждой версии сборки, поэтому видимые значения будут зависеть от кода, вызывающего его.Однако это не объясняет поведение различных значений при доступе к одним и тем же страницам из разных географических местоположений.
  • Я также хотел бы записать в журнал некоторую форму уникальный идентификатор машины , если вы можете, чтобы убедиться, что на одном компьютере работает только одна копия этого кода.«Не доверяй никому, докажи все» - очень полезная эвристика, когда пытаешься понять неясное поведение.
1 голос
/ 05 декабря 2011

Проблема может заключаться в том, что реализованный вами шаблон синглтона не является поточно-ориентированным.поскольку в веб-приложении одновременно запущено несколько потоков (рабочих процессов), два потока создают два разных экземпляра вашего класса.Вы также должны учитывать, где работает ваше веб-приложение.Если вы развернули свое веб-приложение в веб-ферме, может случиться так, что другой веб-сервер получит другой экземпляр вашего класса в виде статической переменной, «живой» в памяти веб-сервера.

1 голос
/ 05 декабря 2011

Ваш веб-сайт может использовать только один пул приложений, но пул приложений может порождать более одного хост-процесса.Проверьте количество рабочих процессов для вашего пула приложений.

0 голосов
/ 05 декабря 2011

Кажется, что ваш статический конструктор не проверяет, был ли экземпляр уже создан.Что-то вроде:

static Singleton()
    {
    if (instance == null)
        {
        instance = new Singleton();
        mutex = new System.Threading.Mutex();
        }
    }

должно гарантировать, что другие методы в классе на самом деле используют тот же "экземпляр", что и instance.

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