С# Многие экземпляры объекта Singleton

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

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

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

Например, в моем офисе мои люди видят аукцион на уровне 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, я регистрирую, кто выполняет это действие.

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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

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