LazyThreadSafetyMode Перечисление

Определение

Определяет, как экземпляр Lazy<T> синхронизирует доступ из нескольких потоков.

public enum class LazyThreadSafetyMode
public enum LazyThreadSafetyMode
type LazyThreadSafetyMode = 
Public Enum LazyThreadSafetyMode
Наследование
LazyThreadSafetyMode

Поля

ExecutionAndPublication 2

Блокировки используются, чтобы убедиться, что только один поток может инициализировать экземпляр Lazy<T> потокобезопасным способом. Фактически метод инициализации выполняется потокобезопасным способом (называется Execution именем поля). Publication инициализированного значения также является потокобезопасным в том смысле, что только одно значение может быть опубликовано и использовано всеми потоками. Если метод инициализации (или конструктор без параметров, если метод инициализации отсутствует) использует внутренние блокировки, могут возникнуть взаимоблокировки. Если вы используете конструктор Lazy<T>, который указывает метод инициализации (параметр valueFactory), и если этот метод инициализации вызывает исключение (или не может обработать исключение) при первом вызове свойства Value, исключение кэшируется и вызывается повторно в последующих вызовах свойства Value. Если вы используете конструктор Lazy<T>, который не указывает метод инициализации, исключения, вызываемые конструктором без параметров для T, не кэшируются. В этом случае последующий вызов свойства Value может успешно инициализировать экземпляр Lazy<T>. Если метод инициализации рекурсивно получает доступ к свойству Value экземпляра Lazy<T>, вызывается InvalidOperationException.

None 0

Экземпляр Lazy<T> не является потокобезопасным; если доступ к экземпляру осуществляется из нескольких потоков, его поведение не определено. Используйте этот режим только в том случае, когда крайне важна высокая производительность, а экземпляр Lazy<T> гарантированно не будет инициализирован больше, чем из одного потока. Если вы используете конструктор Lazy<T>, который указывает метод инициализации (параметр valueFactory), и если этот метод инициализации вызывает исключение (или не может обработать исключение) при первом вызове свойства Value, исключение кэшируется и вызывается повторно в последующих вызовах свойства Value. Если вы используете конструктор Lazy<T>, который не указывает метод инициализации, исключения, вызываемые конструктором без параметров для T, не кэшируются. В этом случае последующий вызов свойства Value может успешно инициализировать экземпляр Lazy<T>. Если метод инициализации рекурсивно получает доступ к свойству Value экземпляра Lazy<T>, вызывается InvalidOperationException.

PublicationOnly 1

Если несколько потоков пытаются инициализировать экземпляр Lazy<T> одновременно, всем потокам разрешено выполнять метод инициализации (или конструктор без параметров, если нет метода инициализации). Первый поток для выполнения инициализации задает значение экземпляра Lazy<T>. Это называется Publication в именах полей. Это значение возвращается в любые другие потоки, которые одновременно выполняли метод инициализации, если метод инициализации не вызывал исключения в этих потоках. Любые экземпляры T, созданные конкурирующими потоками, удаляются. Фактически публикация инициализированного значения является потокобезопасной в том смысле, что только одно из инициализированных значений может быть опубликовано и использовано всеми потоками. Если метод инициализации вызывает исключение в каком-либо потоке, исключение распространяется из свойства Value в этом потоке. Исключение не кэшируется. Значение свойства IsValueCreated остается false, и последующие вызовы свойства Value потоком, где возникло исключение, или другими потоками вызывают повторный запуск метода инициализации. Если метод инициализации рекурсивно получает доступ к свойству Value экземпляра Lazy<T>, исключение не вызывается.

Комментарии

Используйте это перечисление, чтобы указать mode параметр Lazy<T> конструкторов. Влияние всех конструкторов на синхронизацию потоков можно описать с точки зрения этого перечисления независимо от того, имеют mode ли они параметры.

Lazy<T> Экземпляр инициализируется методом инициализации, заданным пользователем, или конструктором без параметров для T. Метод инициализации задается valueFactory параметром конструктора Lazy<T> . Метод возвращает экземпляр T, который является типом, экземпляром которого является отложенный экземпляр Lazy<T>. Если конструктор не имеет valueFactory параметра, конструктор без параметров используется для T инициализации экземпляра Lazy<T> . В любом случае инициализация происходит при первом вызове Lazy<T>.Value свойства.

Помимо указания безопасности потока экземпляра Lazy<T> , это перечисление влияет на кэширование исключений. При кэшировании исключений для экземпляра Lazy<T> вы получаете только один шанс инициализировать экземпляр. Если при первом вызове Lazy<T>.Value свойства возникает исключение, это исключение кэшируется и повторно создается при всех последующих вызовах Lazy<T>.Value свойства. Преимущество кэширования исключений заключается в том, что все два потока всегда получают одинаковый результат, даже если возникают ошибки.

При указании режима PublicationOnly исключения никогда не кэшируются. При указании None или ExecutionAndPublication кэширование зависит от того, указываете ли вы метод инициализации или разрешаете использовать конструктор T без параметров. Указание метода инициализации включает кэширование исключений для этих двух режимов. Метод инициализации может быть очень простым. Например, он может вызвать конструктор без параметров для T: new Lazy<Contents>(() => new Contents(), mode) в C# или New Lazy(Of Contents)(Function() New Contents()) в Visual Basic. Если используется конструктор, не указывающий метод инициализации, исключения, создаваемые конструктором без параметров, T не кэшируются. В следующей таблице приводится сводка по кэшированию исключений.

Режим Использование метода инициализации Использование конструктора без параметров для T
Нет Кэшировано Не кэширован
PublicationOnly Не кэширован Не кэширован
ExecutionAndPublication Кэшировано Не кэширован

Применяется к

См. также раздел