Freigeben über


LazyThreadSafetyMode Enumeration

Definition

Gibt an, wie eine Lazy<T> Instanz den Zugriff zwischen mehreren Threads synchronisiert.

public enum class LazyThreadSafetyMode
public enum LazyThreadSafetyMode
type LazyThreadSafetyMode = 
Public Enum LazyThreadSafetyMode
Vererbung
LazyThreadSafetyMode

Felder

Name Wert Beschreibung
None 0

Die Lazy<T> Instanz ist nicht threadsicher. Wenn von mehreren Threads aus auf die Instanz zugegriffen wird, ist das Verhalten nicht definiert. Verwenden Sie diesen Modus nur, wenn hohe Leistung von entscheidender Bedeutung ist und die Lazy<T> Instanz garantiert niemals aus mehr als einem Thread initialisiert wird. Wenn Sie einen Lazy<T> Konstruktor verwenden, der eine Initialisierungsmethode (valueFactory Parameter) angibt und wenn diese Initialisierungsmethode eine Ausnahme auslöst (oder eine Ausnahme nicht behandelt), wenn Sie die Value Eigenschaft zum ersten Mal aufrufen, wird die Ausnahme zwischengespeichert und bei nachfolgenden Aufrufen der Value Eigenschaft erneut ausgelöst. Wenn Sie einen Lazy<T>-Konstruktor verwenden, der keine Initialisierungsmethode angibt, werden vom parameterlosen Konstruktor für T ausgelöste Ausnahmen nicht zwischengespeichert. In diesem Fall kann ein anschließender Aufruf der Value Eigenschaft die Lazy<T> Instanz erfolgreich initialisieren. Wenn die Initialisierungsmethode rekursiv auf die Value Eigenschaft der Lazy<T> Instanz zugreift, wird ein InvalidOperationException Fehler ausgelöst.

PublicationOnly 1

Wenn mehrere Threads versuchen, eine Lazy<T> Instanz gleichzeitig zu initialisieren, dürfen alle Threads die Initialisierungsmethode (oder den parameterlosen Konstruktor, wenn keine Initialisierungsmethode vorhanden ist) ausführen. Der erste Thread zum Abschließen der Initialisierung legt den Wert der Lazy<T> Instanz fest. Dies wird in den Feldnamen bezeichnet Publication . Dieser Wert wird an alle anderen Threads zurückgegeben, die gleichzeitig die Initialisierungsmethode ausgeführt haben, es sei denn, die Initialisierungsmethode löst Ausnahmen für diese Threads aus. Alle Instanzen, die T von den konkurrierenden Threads erstellt wurden, werden verworfen. Effektiv ist die Veröffentlichung des initialisierten Werts threadsicher in dem Sinne, dass nur einer der initialisierten Werte veröffentlicht und von allen Threads verwendet werden kann. Wenn die Initialisierungsmethode eine Ausnahme für einen Thread auslöst, wird die Ausnahme aus der Value Eigenschaft für diesen Thread verteilt. Die Ausnahme wird nicht zwischengespeichert. Der Wert der IsValueCreated Eigenschaft bleibt erhalten false, und nachfolgende Aufrufe der Value Eigenschaft, entweder durch den Thread, in dem die Ausnahme ausgelöst wurde, oder durch andere Threads führen die Initialisierungsmethode erneut aus. Wenn die Initialisierungsmethode rekursiv auf die Value Eigenschaft der Lazy<T> Instanz zugreift, wird keine Ausnahme ausgelöst.

ExecutionAndPublication 2

Sperren werden verwendet, um sicherzustellen, dass nur ein einzelner Thread eine Lazy<T> Instanz auf threadsichere Weise initialisieren kann. Die Initialisierungsmethode wird effektiv in threadsicherer Weise (wie im Feldnamen bezeichnet Execution ) ausgeführt. Publication des initialisierten Werts ist auch threadsicher in dem Sinne, dass nur ein Wert veröffentlicht und von allen Threads verwendet werden kann. Wenn die Initialisierungsmethode (oder der parameterlose Konstruktor, wenn keine Initialisierungsmethode vorhanden ist) Sperren intern verwendet, können Deadlocks auftreten. Wenn Sie einen Lazy<T> Konstruktor verwenden, der eine Initialisierungsmethode (valueFactory Parameter) angibt und wenn diese Initialisierungsmethode eine Ausnahme auslöst (oder eine Ausnahme nicht behandelt), wenn Sie die Value Eigenschaft zum ersten Mal aufrufen, wird die Ausnahme zwischengespeichert und bei nachfolgenden Aufrufen der Value Eigenschaft erneut ausgelöst. Wenn Sie einen Lazy<T>-Konstruktor verwenden, der keine Initialisierungsmethode angibt, werden vom parameterlosen Konstruktor für T ausgelöste Ausnahmen nicht zwischengespeichert. In diesem Fall kann ein anschließender Aufruf der Value Eigenschaft die Lazy<T> Instanz erfolgreich initialisieren. Wenn die Initialisierungsmethode rekursiv auf die Value Eigenschaft der Lazy<T> Instanz zugreift, wird ein InvalidOperationException Fehler ausgelöst.

Hinweise

Verwenden Sie diese Aufzählung, um den mode Parameter von Lazy<T> Konstruktoren anzugeben. Die Auswirkungen aller Konstruktoren auf die Threadsynchronisierung können in Bezug auf diese Enumeration beschrieben werden, unabhängig davon, ob sie Parameter haben mode .

Eine Lazy<T> Instanz wird entweder durch eine vom Benutzer angegebene Initialisierungsmethode oder durch den parameterlosen Konstruktor für T. Die Initialisierungsmethode wird durch den valueFactory Parameter eines Lazy<T> Konstruktors angegeben. Die Methode gibt eine Instanz von T, die der Typ ist, der von der Instanz von Lazy<T>. Wenn ein Konstruktor keinen Parameter hat valueFactory , wird der parameterlose Konstruktor verwendet T , um die Lazy<T> Instanz zu initialisieren. In beiden Fällen erfolgt die Initialisierung beim ersten Aufrufen der Lazy<T>.Value Eigenschaft.

Zusätzlich zur Angabe der Threadsicherheit einer Lazy<T> Instanz wirkt sich diese Enumeration auf das Zwischenspeichern von Ausnahmen aus. Wenn Ausnahmen für eine Lazy<T> Instanz zwischengespeichert werden, erhalten Sie nur eine Möglichkeit, die Instanz zu initialisieren. Wenn eine Ausnahme ausgelöst wird, wenn Sie die Eigenschaft zum ersten Mal aufrufen, wird diese Lazy<T>.Value Ausnahme zwischengespeichert und bei allen nachfolgenden Aufrufen der Lazy<T>.Value Eigenschaft erneut ausgelöst. Der Vorteil von Cache-Ausnahmen besteht darin, dass alle zwei Threads immer dasselbe Ergebnis erhalten, auch wenn Fehler auftreten.

Wenn Sie den PublicationOnly-Modus angeben, werden Ausnahmen nie zwischengespeichert. Wenn Sie "None" oder "ExecutionAndPublication" angeben, hängt die Zwischenspeicherung davon ab, ob Sie eine Initialisierungsmethode angeben oder den parameterlosen Konstruktor für T die Verwendung zulassen. Durch die Angabe einer Initialisierungsmethode wird das Zwischenspeichern von Ausnahmen für diese beiden Modi aktiviert. Die Initialisierungsmethode kann sehr einfach sein. Sie kann z. B. den parameterlosen Konstruktor für T aufrufen: new Lazy<Contents>(() => new Contents(), mode) in C# bzw. New Lazy(Of Contents)(Function() New Contents()) in Visual Basic. Wenn Sie einen Konstruktor verwenden, der keine Initialisierungsmethode angibt, werden Ausnahmen, die vom parameterlosen Konstruktor T ausgelöst werden, nicht zwischengespeichert. In der folgenden Tabelle sind das Verhalten der Ausnahmezwischenspeicherung zusammengefasst.

Modus Verwenden der Initialisierungsmethode Verwenden des parameterlosen Konstruktors für T
Nichts Zwischengespeichert Nicht zwischengespeichert
PublikationOnly Nicht zwischengespeichert Nicht zwischengespeichert
ExecutionAndPublication Zwischengespeichert Nicht zwischengespeichert

Gilt für:

Weitere Informationen