В случае, когда ленивому нужен доступ к элементам экземпляра, а не к статическим членам, где ленивый инициализируется внутри конструктора класса, автоматически ли для этого требуется isThreadSafe: false во всех случаях?
Нет- Аргумент isThreadSafe
влияет только на то, как создается значение в Lazy<T>
.
По сути, когда вы устанавливаете значение false, метод для создания значения просто создает значение, устанавливая его навнутреннее хранилище и верните значение.
Если вы установите его в значение true, то создание будет помещено в lock
, предотвращая создание объекта более чем одним потоком.Это сопоставляется с LazyThreadSafetyMode.ExecutionAndPublication .
Вы также можете явно указать PublicationOnly
, что позволит создать более одного значения, но затем использовать Interlocked.CompareExchange внутренне вместо блокировки, чтобы удостовериться, что значение первой завершенной подпрограммы создания является тем, которое используется для объекта.
Обратите внимание, что ни один из этих параметров вообще не влияет на то, какие члены используются для вычислениязначение - они влияют только на то, как создается само значение.Доступ ко всему кроме создания всегда потокобезопасен.Если вы инициализируете Lazy<T>
экземпляр элемента в конструкторе класса, вы фактически гарантируете, что синхронизация не требуется, поэтому вы можете установить для isThreadSafe
значение false - но это также будет означатьчто нет абсолютно никакой причины использовать Lazy<T>
в этой ситуации, так как вы используете явную реализацию ...