Condividi tramite


LazyThreadSafetyMode Enumerazione

Definizione

Specifica il modo in cui un'istanza di Lazy<T> sincronizza l'accesso tra più thread.

public enum class LazyThreadSafetyMode
public enum LazyThreadSafetyMode
type LazyThreadSafetyMode = 
Public Enum LazyThreadSafetyMode
Ereditarietà
LazyThreadSafetyMode

Campi

Nome Valore Descrizione
None 0

L'istanza Lazy<T> non è thread-safe. Se si accede all'istanza da più thread, il comportamento non è definito. Usare questa modalità solo quando le prestazioni elevate sono cruciali e l'istanza Lazy<T> non viene mai inizializzata da più di un thread. Se si usa un costruttore che specifica un Lazy<T> metodo di inizializzazione (valueFactory parametro) e se tale metodo di inizializzazione genera un'eccezione (o non riesce a gestire un'eccezione) la prima volta che si chiama la Value proprietà, l'eccezione viene memorizzata nella cache e generata nuovamente nelle chiamate successive alla Value proprietà. Se si usa un costruttore Lazy<T> che non specifica un metodo di inizializzazione, le eccezioni generate dal costruttore senza parametri per T non vengono memorizzate nella cache. In tal caso, una chiamata successiva alla Value proprietà potrebbe inizializzare correttamente l'istanza Lazy<T> . Se il metodo di inizializzazione accede in modo ricorsivo alla Value proprietà dell'istanza Lazy<T> di , viene generata un'eccezione InvalidOperationException .

PublicationOnly 1

Quando più thread tentano di inizializzare un'istanza Lazy<T> contemporaneamente, tutti i thread possono eseguire il metodo di inizializzazione (o il costruttore senza parametri, se non esiste alcun metodo di inizializzazione). Il primo thread per completare l'inizializzazione imposta il valore dell'istanza Lazy<T> . Questo nome viene definito nei Publication nomi dei campi. Tale valore viene restituito a tutti gli altri thread che eseguono contemporaneamente il metodo di inizializzazione, a meno che il metodo di inizializzazione non generi eccezioni in tali thread. Tutte le istanze di T create dai thread concorrenti vengono eliminate. In effetti, la pubblicazione del valore inizializzato è thread-safe nel senso che solo uno dei valori inizializzati può essere pubblicato e usato da tutti i thread. Se il metodo di inizializzazione genera un'eccezione in qualsiasi thread, l'eccezione viene propagata all'esterno Value della proprietà in tale thread. L'eccezione non viene memorizzata nella cache. Il valore della IsValueCreated proprietà rimane falsee le chiamate successive alla Value proprietà, dal thread in cui è stata generata l'eccezione o da altri thread, causano l'esecuzione del metodo di inizializzazione. Se il metodo di inizializzazione accede in modo ricorsivo alla Value proprietà dell'istanza Lazy<T> di , non viene generata alcuna eccezione.

ExecutionAndPublication 2

I blocchi vengono usati per garantire che solo un singolo thread possa inizializzare un'istanza Lazy<T> in modo thread-safe. In effetti, il metodo di inizializzazione viene eseguito in modo thread-safe (noto come Execution nel nome del campo). Publication del valore inizializzato è anche thread-safe nel senso che solo un valore può essere pubblicato e usato da tutti i thread. Se il metodo di inizializzazione (o il costruttore senza parametri, se non è presente alcun metodo di inizializzazione) utilizza internamente blocchi, possono verificarsi deadlock. Se si usa un costruttore che specifica un Lazy<T> metodo di inizializzazione (valueFactory parametro) e se tale metodo di inizializzazione genera un'eccezione (o non riesce a gestire un'eccezione) la prima volta che si chiama la Value proprietà, l'eccezione viene memorizzata nella cache e generata nuovamente nelle chiamate successive alla Value proprietà. Se si usa un costruttore Lazy<T> che non specifica un metodo di inizializzazione, le eccezioni generate dal costruttore senza parametri per T non vengono memorizzate nella cache. In tal caso, una chiamata successiva alla Value proprietà potrebbe inizializzare correttamente l'istanza Lazy<T> . Se il metodo di inizializzazione accede in modo ricorsivo alla Value proprietà dell'istanza Lazy<T> di , viene generata un'eccezione InvalidOperationException .

Commenti

Utilizzare questa enumerazione per specificare il mode parametro dei Lazy<T> costruttori. Gli effetti di tutti i costruttori sulla sincronizzazione dei thread possono essere descritti in termini di questa enumerazione, indipendentemente dal fatto che abbiano mode o meno parametri.

Un'istanza Lazy<T> viene inizializzata da un metodo di inizializzazione specificato dall'utente o dal costruttore senza parametri per T. Il metodo di inizializzazione viene specificato dal valueFactory parametro di un Lazy<T> costruttore. Il metodo restituisce un'istanza di T, ovvero il tipo di cui viene creata un'istanza differita dall'istanza di Lazy<T>. Se un costruttore non dispone di un valueFactory parametro, viene usato il costruttore senza parametri per T per inizializzare l'istanza Lazy<T> . In entrambi i casi, l'inizializzazione viene eseguita la prima volta che si chiama la Lazy<T>.Value proprietà .

Oltre a specificare la thread safety di un'istanza Lazy<T> , questa enumerazione influisce sulla memorizzazione nella cache delle eccezioni. Quando le eccezioni vengono memorizzate nella cache per un'istanza Lazy<T> di , si ottiene una sola possibilità di inizializzare l'istanza. Se viene generata un'eccezione la prima volta che si chiama la Lazy<T>.Value proprietà , tale eccezione viene memorizzata nella cache e rigenerata in tutte le chiamate successive alla Lazy<T>.Value proprietà . Il vantaggio della memorizzazione nella cache delle eccezioni è che qualsiasi due thread ottiene sempre lo stesso risultato, anche quando si verificano errori.

Quando si specifica la modalità PublicationOnly, le eccezioni non vengono mai memorizzate nella cache. Quando si specifica None o ExecutionAndPublication, la memorizzazione nella cache dipende dal fatto che si specifichi un metodo di inizializzazione o che il costruttore senza parametri venga T usato. Se si specifica un metodo di inizializzazione, la memorizzazione nella cache delle eccezioni viene abilitata per queste due modalità. Il metodo di inizializzazione può essere molto semplice. Ad esempio, può chiamare il costruttore senza parametri per T: new Lazy<Contents>(() => new Contents(), mode) in C# o New Lazy(Of Contents)(Function() New Contents()) in Visual Basic. Se si usa un costruttore che non specifica un metodo di inizializzazione, le eccezioni generate dal costruttore senza parametri per T non vengono memorizzate nella cache. Nella tabella seguente viene riepilogato il comportamento di memorizzazione nella cache delle eccezioni.

Modalità Uso del metodo di inizializzazione Uso del costruttore senza parametri per T
Nessuno Memorizzati nella cache Non memorizzato nella cache
PublicationOnly Non memorizzato nella cache Non memorizzato nella cache
ExecutionAndPublication Memorizzati nella cache Non memorizzato nella cache

Si applica a

Vedi anche