powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Потокобезопасный singleton от Ninject
25 сообщений из 32, страница 1 из 2
Потокобезопасный singleton от Ninject
    #39590220
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, есть необходимость создать потокобезопасный синглтон, чтобы можно было менять в нем данные из разных потоков. К сожалению в документации не нашел 100% ответ будет ли он безопасный в зависимости от разных условий инициализаций. Попытался сам проверить потокобезопасность следующими тестами.

Код: c#
1.
2.
3.
4.
5.
6.
// класс, который должен быть одиночкой

 public class DataStore
    {
        public string Name { get; set; }
    }



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
Kernel.Bind<DataStore>().ToSelf().InSingletonScope();
//thread-safe Tests

         (new System.Threading.Thread(() =>
            {
                DataLayer.DataStore r1 = ioc.Ioc.Get<DataLayer.DataStore>();
                r1.Name = "From BackgroundThread";
                Debug.WriteLine(r1.Name);
            })).Start();

            DataLayer.DataStore r = ioc.Ioc.Get<DataLayer.DataStore>();
            r.Name = "FromMainthread";
            Debug.WriteLine(r.Name);
//output
//FromMainthread
//FromMainthread
/////////////////////////////////

// те же самые тесты
 Kernel.Bind<Lazy<DataStore>>().ToConstant(new Lazy<DataStore>(
() => new DataStore()
)).InThreadScope();

//From BackgroundThread
//Поток 0x3714 завершился с кодом 0 (0x0).
//FromMainthread

/////////////////////////////////

 Kernel.Bind<DataStore>().ToSelf().InSingletonScope();

//FromMainthread
//FromMainthread



Вопрос- позволяет ли данные второго теста (Kernel.Bind<Lazy<DataStore>>().ToConstant(new Lazy<DataStore>(
() => new DataStore()
)).InThreadScope();) утверждать, что синглтон потокобезопасен?
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590278
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub,
Объект безопасный, если все его поля до пятого колена безопасны.
Вывод, бери безопасные коллекции.....типа ConcurrenrDictionary.
Но у меня иногда и это глючит без блокировки.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590307
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Под потокобезопасностью синглтона подразумевается не потокобезопасность его методов или состояния, а потокобезопасное создание экземпляра синглтона ( см. у Скита ). То, что некий класс является [потокобезопасным] синглтоном, и то, что его свойства/методы потокобезопасны - вещи ортогональные.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590308
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и синглетон не имеет отношения к сабжу.
Синглетон - экземпляры, а ThreadSafe - доступ.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590309
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,
Спс за ссылку.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590311
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub,
У меня список для потокового доступа просто находится рядом с главной формой ГУИ. И не надо синглетона).
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590373
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныПод потокобезопасностью синглтона подразумевается не потокобезопасность его методов или состояния, а потокобезопасное создание экземпляра синглтона ( см. у Скита ). То, что некий класс является [потокобезопасным] синглтоном, и то, что его свойства/методы потокобезопасны - вещи ортогональные.

Я не спец в ninject, но, думаю, что как и всякий приличный DI-контейнер, он должен обеспечить безопасное создание синглетона из коробки без всяких дополнительных телодвижений.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590375
Pu4koff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ninject в глаза не видел, так что могу наврать.
InThreadScope по идее указывает на то, что на каждый поток будет создан свой экземпляр "синглтона", т.е. сам класс объекта может быть и не потокобезопасным и у каждого потока будет свой DataStore и своё значение свойства Name.
Если делать Lazy прям синглтон, что один для всех, то:
Класс Lazy, согласно msdn является потокобезопасным, но вот сам DataStore таким не является.
как-то так получается:
Код: c#
1.
2.
3.
var lazy = Kernel.Get<Lazy<DataStore>>(); // норм
var ds = lazy.Value; // норм
ds.Name = ...; // не норм, если операция не будет атомарной, если в set'тер будет добавлена какая-то валидация, например.


В общем, Lazy ничего не даёт и не нужен тут. Ninject и сам по сути роль Lazy выполняет. DataStore конкретно в данном случае синхронизировать не нужно, т.к. на каждый поток будет свой экземпляр. Если прописать InSingletonScope(), тогда и DataStore нужно thread-safe'ить.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590405
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pu4koff,
на lazy не стоит заострать внимание-он просто делает отложенную инициализация, на потокобезопасность никак не влияет.
Стандартно советуют делать синглтон с lock для поткобезопасности, но он расточителен по ресурсам.
Еще метанит приводит такой пример потокобезопасного синглтона без лока
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public class Singleton
{
    private static readonly Singleton instance = new Singleton();
 
    public string Name { get; private set; }
 
    private Singleton()
    {
        Name = System.Guid.NewGuid().ToString();
    }
 
    public static Singleton GetInstance()
    {
        return instance;
    }
}

только не очень понятно как Guid сделает его потокобезопасным.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590409
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subСтандартно советуют делать синглтон с lock для поткобезопасности, но он расточителен по ресурсам.
Еще метанит приводит такой пример потокобезопасного синглтона без лока

Я вообще не понимаю - кому в наш век повсеместного DI может понадобиться писать свой синглтон.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590411
Pu4koff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub, под потокобезопасным синглтоном понимают то, что при получении объекта из разных потоков будет получен один и тот же объект. Это не значит что сам объект потокобезопасен, а только то, что можно одновременно вызвать метод:
Код: c#
1.
Singleton.GetInstance()


и получить один и тот же объект.
В примере guid используется чисто для проверки. Типа можно запустить кучу потоков, в них выполнить:
Код: c#
1.
Console.WriteLine(Singleton.GetInstance().Name);


и получить одну и ту же строку.
Потокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами.
При работе с такими "потокобезопасными" синглтонами нужно просто помнить и о потокобезопасности самого объекта, тут обезопасили только метод Singleton.GetInstance() и не более того.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590413
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subСтандартно советуют делать синглтон с lock для поткобезопасности, но он расточителен по ресурсам.

Даблчек-лок практически не даст оверхеда, разве что кроме первого вызова.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590415
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
string потокобезопасен поэтому твоя обертка на над ним тоже потокобезопасна.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590416
Pu4koff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat, я вообще думал, что синглтоны уже несколько лет как перевели в антипаттерны :)
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590422
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pu4kofffkthat, я вообще думал, что синглтоны уже несколько лет как перевели в антипаттерны :)+1
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590426
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pu4kofffkthat, я вообще думал, что синглтоны уже несколько лет как перевели в антипаттерны :)

Да херь все это от Башни Слонячей Кости. Точно так же можно сказать, что конструктор это антипаттерн, а использовать надо только фабрики, а еще лучше абстрактные фабрики. К тому же я уже вообще и забыл, как объекты руками создавать - у нас везде когда что-то надо, то добавляешь в конструктор, а IoC сам туда всунет что нужно - синглтон там или не синглтон, или даже вообще какой-то обьект в другом процессе - меня, как его потребителя, это вообще не парит - это забота того, кто контейнер конфигурирует и самого контейнера.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590427
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
 public class DataStore
    {
public ObservableCollection<FakeClass> FakeList { get; set; }
    }


то есть если я предполагаю, что FakeList будет редактироваться из разных потоков, и я не хочу, чтобы какие- либо изменения пропали мне нужно искать Thread-Safe ObservableCollection<T> обертку?
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590430
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subто есть если я предполагаю, что FakeList будет редактироваться из разных потоков, и я не хочу, чтобы какие- либо изменения пропали мне нужно искать Thread-Safe ObservableCollection<T> обертку?

Да. Использовать ReaderWriterLock или ReaderWriterLockSlim.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590432
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub,

По хорошему, надо не допускать редактирования ресурса из разных потоков.
Нарезать куски работы для каждого потока - вот такой хайп параллельности.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590448
Pu4koff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat, это всё из-за модников-неучей. Сначала лепили статические классы. Потом начали задумываться о времени жизни объектов, о реализации интерфейсов и т.д. и т.п. и ломанулись использовать синглтон, типа это такая серебряная пуля, всем и всегда поможет. Статикам табу, синглтонам - милости просим. Потом опять голову включили и оказалось, что у синглтонов тоже не всё круто. Теперь им табу, а на коне всякие DI и сотоварищи.
По факту просто всему своё место. И статические классы норм и синглтоны и т.д. и т.п. Законодателям моды проще было сказать, что синглтоны не комильфо пользовать.

vb_sub, не забываем еще и про потокобезопасность FakeClass, если возможна работа с одним объектом коллекции из разных потоков.
Если разные потоки могут забрать один и тот же элемент коллекции и как-то его менять, тогда его внутренности тоже нужно защищать.
И всё равно там не всё так однозначно будет.
Типа напишете DataStore.Name = DataStore.Name + DataStore.Name
по отдельности всё безопасно, а в сумме одна большая беда.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590466
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subPu4koff,
на lazy не стоит заострать внимание-он просто делает отложенную инициализация, на потокобезопасность никак не влияет.
вообще то в Lazy<T> реализована потоколбезопасность, по этому из 2 потоков получить 2 разных ленивых объекта не получится. https://referencesource.microsoft.com/#mscorlib/system/Lazy.cs,8b99c1f377873554, там даже в конструкторе есть параметр ThreadSafe
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590491
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pu4koffПотокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами.
Неправильно. Статическое readonly поле - всего лишь для хранения экземпляра, само по себе оно ничего не гарантирует, потокобезопасность там реализуется либо за счет вручную прописанных локов, либо за счет манпуляций с IL-флагом beforefieldinit , либо за счет обеспечивающих потокобезопасность классов FCL (Lazy<T>).
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590508
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныPu4koffПотокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами.
Неправильно. Статическое readonly поле - всего лишь для хранения экземпляра, само по себе оно ничего не гарантирует, потокобезопасность там реализуется либо за счет вручную прописанных локов, либо за счет манпуляций с IL-флагом beforefieldinit , либо за счет обеспечивающих потокобезопасность классов FCL (Lazy<T>).

Кури спеки. Инициализация статического поля компилятором помещается либо в начало существующего статического конструктора, либо, при отсутствии оного, в сгенерированный. Статический конструктор всегда вызывается в потокобезопасной манере - хоть сколько потоков одновременно обратятся к классу, статический конструктор вызовется только один раз, одним потоком и до выполнения любого кода того же класса. Т.ч. реализовывать синглтон через статическое поле это и есть самый эффективный и простой метод - а всё это дрочево с локами, двойной проверкой и проч. - это только чтобы джуниоров на интервью погномить.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590511
Pu4koff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныPu4koffПотокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами.
Неправильно. Статическое readonly поле - всего лишь для хранения экземпляра, само по себе оно ничего не гарантирует, потокобезопасность там реализуется либо за счет вручную прописанных локов, либо за счет манпуляций с IL-флагом beforefieldinit , либо за счет обеспечивающих потокобезопасность классов FCL (Lazy<T>).
так в этом и смысл синглтона, что там ровно один экземпляр. Ровно это и даёт статический член класса с инициализацией.
такой синглтон не потокобезопасный:
Код: c#
1.
2.
3.
4.
5.
6.
static A GetInstance()
{
  if (_instance == null)
    _instance = new A();
  return _instance;
}


если if обернуть в тот же lock, тогда уже типа будет потокобезопасный синглтон, но это не значит, что стал потокобезопасным возвращенный объект типа А.

при таком варианте:
Код: c#
1.
private static readonly Singleton instance = new Singleton();


невозможна же ситуация, что instance в разное время будет ссылаться на разные объекты или что инициализатор new Singleton() отработает несколько раз для разных потоков? А большего от синглтона и его потокобезопасности и не нужно.
...
Рейтинг: 0 / 0
Потокобезопасный singleton от Ninject
    #39590581
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatКури спеки. Инициализация статического поля компилятором помещается либо в начало существующего статического конструктора, либо, при отсутствии оного, в сгенерированный. Статический конструктор всегда вызывается в потокобезопасной манере - хоть сколько потоков одновременно обратятся к классу, статический конструктор вызовется только один раз, одним потоком и до выполнения любого кода того же класса. Т.ч. реализовывать синглтон через статическое поле это и есть самый эффективный и простой метод - а всё это дрочево с локами, двойной проверкой и проч. - это только чтобы джуниоров на интервью погномить.
Кури человеческую реализацию паттерна. Инициализация поля экземпляра синглтона в статик-конструкторе в общем случае делает его не ленивым - см. выше про флаг beforefieldinit. Поскольку мало кто представляет все нюансы этого флага, то для перестраховки выносят инициализацию инстанса из статического инициализатора типа, и оборачивают в локи - так добиваются и ленивости, и потокобезопасности. Кто представляет - использует пустой статик-конструктор, и тоже не инициализирует инстанс в статическом конструкторе (т.к. мым можем в коде обратиться к константе класса синглтона, или к статик-методу, не связанному с инстансом - а у нас всё равно будет создан экземпляр).
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Потокобезопасный singleton от Ninject
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]