День 2464. #ЗаметкиНаПолях****Потокобезопасная Инициализация с Помощью LazyInitializer Хотя Lazy является основным решением для ленивой инициализации в .NET, существует менее известная альтернатива, которая может быть более эффективной в некоторых сценариях: LazyInitializer.EnsureInitialized.

Этот статический метод обеспечивает потокобезопасную инициализацию с рядом ключевых характеристик:

  • Только ссылочные типы: работает только с классами, но не со значениями.
  • Обнаружение на основе NULL: использует значение NULL для определения необходимости инициализации.
  • Эффективное использование памяти по сравнению с System.Lazy: не требуется дополнительный объект-обёртка.

Метод предлагает несколько перегрузок для различных сценариев: `Sample? _instance = null;

// Инициализация через конструктор по умолчанию var instance = LazyInitializer.EnsureInitialized(ref _instance);

// Фабричный метод var instance = LazyInitializer.EnsureInitialized( ref _instance, () => new Sample() );

// Фабричный метод вызывается 1 раз, даже если нескольким потокам требуется инициализация var syncLock = new object(); var instance = LazyInitializer.EnsureInitialized( ref _instance, ref syncLock, () => new Sample() );

Замечания по потокобезопасности По умолчанию LazyInitializer.EnsureInitialized ведёт себя как LazyThreadSafetyMode.PublicationOnly: Несколько потоков могут создавать экземпляры одновременно. Сохраняется только первое успешное назначение. Остальные экземпляры отбрасываются. Для строгой потокобезопасности используйте перегрузку с блокировкой синхронизации, чтобы гарантировать, что фабричный метод будет выполнен только один раз.

Внутренняя реализация этого аналогична следующему коду: `var instance = Volatile.Read(ref _instance) ?? Interlocked.CompareExchange( ref _instance, new Sample(), null);

Преимущества Главное преимущество перед Lazy — вместо хранения объекта-обёртки Lazy вы напрямую используете целевой экземпляр. Также это снижает затраты памяти, экономя одно поле на каждое лениво инициализированное значение.

Источник: *https://www.meziantou.net/thread-safe-initialization-with-lazyinitializer.htm*``