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

ExecutionAndPublication 2

Per garantire che solo un singolo thread possa inizializzare un'istanza di Lazy<T> in modalità thread-safe, vengono usati i blocchi. In modo efficace, il metodo di inizializzazione viene eseguito in modo thread-safe (definito Execution nel nome del campo). Publication del valore inizializzato è anche thread-safe nel senso che un solo valore può essere pubblicato e usato da tutti i thread. Se il metodo di inizializzazione (o il costruttore senza parametri se non esiste alcun metodo di inizializzazione) usa i blocchi internamente, possono verificarsi deadlock. Se si usa un costruttore di Lazy<T> che specifica un metodo di inizializzazione (parametro valueFactory) e se tale metodo di inizializzazione genera un'eccezione (o non è in grado di gestire un'eccezione) la prima volta che si chiama la proprietà Value, l'eccezione viene memorizzata nella cache e generata di nuovo per le chiamate successive alla proprietà Value. 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, è possibile che una chiamata successiva alla proprietà Value inizializzi correttamente l'istanza di Lazy<T>. Se il metodo di inizializzazione accede in modo ricorsivo alla proprietà Value dell'istanza di Lazy<T>, verrà generata un'eccezione InvalidOperationException.

None 0

L'istanza di Lazy<T> non è thread-safe. Se l'istanza è accessibile da più thread, il comportamento sarà indefinito. Usare questa modalità solo quando è fondamentale ottenere prestazioni elevate e l'istanza di Lazy<T> non potrà mai essere inizializzata da più thread. Se si usa un costruttore di Lazy<T> che specifica un metodo di inizializzazione (parametro valueFactory) e se tale metodo di inizializzazione genera un'eccezione (o non è in grado di gestire un'eccezione) la prima volta che si chiama la proprietà Value, l'eccezione viene memorizzata nella cache e generata di nuovo per le chiamate successive alla proprietà Value. 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, è possibile che una chiamata successiva alla proprietà Value inizializzi correttamente l'istanza di Lazy<T>. Se il metodo di inizializzazione accede in modo ricorsivo alla proprietà Value dell'istanza di Lazy<T>, verrà generata un'eccezione InvalidOperationException.

PublicationOnly 1

Quando più thread tentano di inizializzare un'istanza di 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 la cui inizializzazione viene completata imposta il valore dell'istanza di Lazy<T>. Questo valore viene definito Publication nei nomi dei campi. Questo valore viene restituito a qualsiasi altro thread che esegue simultaneamente il metodo di inizializzazione, a meno che il metodo di inizializzazione non generi eccezioni per tali thread. Tutte le istanze di T che sono state create dai thread concorrenti vengono ignorate. In modo efficace, 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 fuori dalla proprietà Value sul thread interessato. L'eccezione non viene memorizzata nella cache. Il valore della proprietà IsValueCreated rimane false e le chiamate successive alla proprietà Value proprietà (da parte del thread in cui è stata generata l'eccezione o da parte di altri thread) comporta la riesecuzione del metodo di inizializzazione. Se il metodo di inizializzazione accede in modo ricorsivo alla proprietà Value dell'istanza di Lazy<T>, non verrà generata alcuna eccezione.

Commenti

Usare questa enumerazione per specificare il mode parametro dei Lazy<T> costruttori. Gli effetti di tutti i costruttori nella sincronizzazione dei thread possono essere descritti in termini di questa enumerazione, indipendentemente dal fatto che abbiano mode 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 che viene creata in modo più immediato dall'istanza di Lazy<T>. Se un costruttore non ha un valueFactory parametro, il costruttore senza parametri per T viene usato per inizializzare l'istanza Lazy<T> . In entrambi i casi, l'inizializzazione si verifica la prima volta che si chiama la Lazy<T>.Value proprietà.

Oltre a specificare la sicurezza del thread 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> , si ottiene solo una possibilità di inizializzare l'istanza. Se viene generata una eccezione la prima volta che si chiama la Lazy<T>.Value proprietà, tale eccezione viene memorizzata nella cache e viene rethrown in tutte le chiamate successive alla Lazy<T>.Value proprietà. Il vantaggio delle eccezioni di memorizzazione nella cache è che i due thread ottengono 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 specifica un metodo di inizializzazione o si consenta l'uso del costruttore senza parametri.T 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, potrebbe 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 Richieste nella cache Non memorizzato nella cache
PublicationOnly Non memorizzato nella cache Non memorizzato nella cache
ExecutionAndPublication Richieste nella cache Non memorizzato nella cache

Si applica a

Vedi anche